' },
});
console.log(userResponse.output_text);
```
See [End-user identity](/docs/end-user-identity) for scoping and [API reference](/api-reference/introduction) for the exact MKA1 contract.
# Organization setup
Source: https://docs.mka1.com/docs/organization-setup
Accept an invite and set up an organization in an existing MKA1 cluster.
A cluster invite creates an organization in an existing deployment. It does not deploy a cluster. If you already have an API key, start with the [developer quickstart](/docs/quickstart).
## Accept your cluster invite
Open the cluster invite link your administrator sent you. It carries a one-time token and lands you on the **Set up your organization** page. A cluster invite is an **owner invite** - accepting it creates a new organization and sets you as the owner. Your administrator may also have preset a request quota and enabled compute on the invite, so the new organization starts with those in place.
### Do this
1. **Open the invite link.** The page validates the token and shows an *Owner invite* badge (and an expiry date, if one was set). If it says the invite is unavailable, the invite token has expired or been revoked. Ask your administrator for a fresh link.
2. **Name your organization.** Type a name such as Acme Inc, and upload a logo if you have one (PNG, JPEG, WebP, GIF, or SVG, up to 5 MB). A workspace URL slug is generated for you (e.g. acme-inc); expand **Customize** if you want to edit it. A slug is 1 to 64 characters: lowercase letters, numbers, and hyphens. If a slug is reserved or already taken, the server rejects it and you pick another.
3. **Choose how to sign in.** Create an account with email and password, or continue with Google. If the invite was pinned to your email address, that address is pre-filled and locked.
4. **Verify your email.** If you signed up with a password, MKA1 sends a verification email. Click the link to confirm; you're then dropped straight into your new organization.
5. **Walk through the setup wizard.** You land in a short setup wizard, not the dashboard. Its steps run in this order: Enable your models (runs automatically), Invite your team, Create teams, Create your first API key, Create your first response, and You're all set. Every step except the last has a **Skip for now** button, and each page links back to this guide. The models step is covered under **Enable your models** below. See [Teams and members](/docs/teams-and-members), [API keys](/docs/authentication), and [Quickstart](/docs/quickstart) for those steps. The key the wizard creates uses the Standard preset and no rate limit. When you finish, you land in the console as the **owner** of your organization.
**You are now the organization owner**
The owner has full control. Usage, members, teams, and settings. Everyone else you bring in will be an admin or a member (see [Teams and members](/docs/teams-and-members)). If you were already signed in to MKA1 with a different email than the invite, sign out first: invites are bound to a specific address.
### Enable your models
Your cluster keeps a catalog of models, and each organization has its own registry. A cluster admin grants your organization access to catalog models, either in the invite's **Model access** picker or later under **Access → Organizations → Cluster**, on your organization's **Available models** tab, but access alone does nothing. You must activate a model in your organization's registry before any request can resolve it, and that includes `model: "auto"`; the gateway never activates a model on its own. The wizard's first step activates every available cluster model you have access to, as long as nothing in your registry is active yet.
If you skipped that step, or the cluster admin adds models later, go to **Admin → Model Registry → Models** and click **Activate**. Each entry shows `available`, `active`, or **name in use** (`available_name_blocked` in the API). **Name in use** means another entry already holds that id, so deactivate that entry first. You can do the same over the API: list the catalog with `sdk.llm.models.listCatalog()` and activate an entry with `sdk.llm.models.activateRegistryEntry({ modelId, source: 'cluster' })` (in Python, `sdk.llm.models.list_catalog()` and `sdk.llm.models.activate_registry_entry(model_id=..., source="cluster")`). The [Model registry](/docs/model-registry) guide covers the catalog, the activation states, and what `auto` resolves to.
## Next steps
[Create an API key](/docs/authentication), [invite your team](/docs/teams-and-members), or explore the [console](/docs/console-tour).
# Overview
Source: https://docs.mka1.com/docs/platform-getting-started
Build with MKA1 or explore the platform behind your deployment.
MKA1 provides a shared API for models, conversations, tools, agents, and evaluations. You can use the hosted platform or a deployment operated by your organization.
This section has moved to SDKs.
This section has moved to Speech.
## Build an application
Already have an API key? Start with the [Quickstart](/docs/quickstart). Choose a client and make one request, then explore [Responses](/docs/responses) to combine inputs, retrieval, tools, and outputs.
Make your first API request.
Choose how your application calls MKA1.
Save model instructions and run agents with tools.
Measure behavior with tasks, datasets, and graders.
## Understand or operate a deployment
Want to see a complete application built on the MKA1 API? Explore [MKA1 Code](/docs/mka1-code), a pre-built coding application for desktop, VS Code, and the terminal.
Start with the [Platform overview](/docs/platform-overview) for architecture, requirements, capabilities, and evidence. If you have an invitation to an existing cluster, follow [Organization setup](/docs/organization-setup).
## Explore capabilities
* [Responses](/docs/responses), [streaming](/docs/streaming), and [conversations](/docs/conversations).
* [Images and documents](/docs/multimodal-input), [speech](/docs/speech), and [realtime voice](/docs/advanced-voice-mode).
* [Files and retrieval](/docs/files-and-vector-stores), [structured extraction](/docs/extract-structured-data), and [prompt templates](/docs/prompt-repository).
* [MCP tools](/docs/mcp-tools), [sandbox sessions](/docs/sandbox), and [agent memory](/docs/build-an-agent-with-memory-stores).
* [Compute](/docs/compute): datasets, training workloads, and model serving.
# Platform overview
Source: https://docs.mka1.com/docs/platform-overview
Understand what MKA1 deploys and how to evaluate and administer the platform.
MKA1 brings model access, application APIs, and administration into a Kubernetes-based platform. Customers can operate a deployment for their own teams and downstream applications.
The console and API expose the same platform capabilities. Developers integrate through SDKs and the CLI; administrators manage access, models, usage, and policies.
## Understand the deployment
* [Architecture](/docs/architecture/overview) shows the gateway, services, control planes, and shared state.
* [Requirements](/docs/architecture/requirements) describes the platform’s Kubernetes, storage, and capacity needs. Model-serving GPU capacity is sized separately.
* [GitOps and rollback](/docs/gitops-atomic-rollback) documents deployment controls and their evidence. It is not a cluster installation runbook.
## Explore what teams can build
Explore a pre-built coding application powered by the MKA1 API, with desktop, VS Code, and terminal workflows.
| Capability | Start here |
| - | - |
| Text, conversations, and streaming | [Text generation](/docs/generate-a-response) |
| Documents, images, and audio | [Multimodal input](/docs/multimodal-input), [Speech](/docs/speech) |
| Retrieval over customer documents | [Files and retrieval](/docs/files-and-vector-stores) |
| Reusable agents, memory, and integrations | [Agents](/docs/managing-agents) |
| Model-quality measurement | [Evals](/docs/evals) |
| Training and model hosting | [Compute](/docs/compute) |
## Set up an organization
An organization is a tenant within a deployment. Accepting a cluster invite creates an organization; it does not install the platform.
1. Follow [Organization setup](/docs/organization-setup).
2. Use the [Console tour](/docs/console-tour) to locate the available tools.
3. Manage [Teams and members](/docs/teams-and-members) and [Service accounts](/docs/service-accounts).
4. Activate models in the [Model registry](/docs/model-registry).
5. Give developers appropriately scoped [API keys](/docs/authentication).
## Operate and evaluate
* Configure [Auto routing](/docs/auto-routing), [Budgets](/docs/budgets), and [Rate limits](/docs/rate-limiting).
* Inspect [Usage and auditing](/docs/usage-auditing).
* Review [Resource permissions](/docs/authorization) and [Tenant isolation](/docs/authentication-deep-dive).
* Review [Data encryption](/docs/data-encryption), [HSM-backed keys and TLS 1.3](/docs/hsm-tls-validation), and [Signed artifacts](/docs/signed-artifacts).
* Evaluate the published [latency](/docs/streaming-output-latency), [retrieval](/docs/evaluating-text-stores), and [GraphRAG](/docs/graphrag) results against your own workload.
Evidence pages describe the environments and methods they tested. Check those details when assessing a different deployment.
# Prompt templates
Source: https://docs.mka1.com/docs/prompt-repository
Manage versioned prompt templates with change history, rollback, and variable rendering through the Prompts API.
The Prompts API lets you store, version, and manage prompt templates centrally.
Every template change creates an immutable version, giving you a full change history
with the ability to roll back to any previous version at any time.
Templates support `{{variable}}` placeholders that are rendered server-side when you
retrieve a prompt, so you can reuse the same template across different contexts.
## Create a prompt
Create a prompt with a name and template. The first version is created automatically.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const result = await sdk.llm.prompts.create({
xOnBehalfOf: '', // optional — attribute the request to one of your end users
createPromptRequest: {
name: 'greeting',
description: 'A simple greeting template',
template: 'Hello, {{name}}! Welcome to {{company}}.',
metadata: { team: 'onboarding' },
},
});
console.log(result.id); // prompt_abc123...
console.log(result.activeVersion); // 1
console.log(result.version?.version); // 1
const promptId = result.id; // used in the examples below
```
```python Python SDK theme={null}
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
result = sdk.llm.prompts.create(
name="greeting",
description="A simple greeting template",
template="Hello, {{name}}! Welcome to {{company}}.",
metadata={"team": "onboarding"},
)
print(result.id) # prompt_abc123...
print(result.active_version) # 1
print(result.version.version) # 1
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Components;
using MeetKai.MKA1.Types.Requests;
var sdk = new SDK(bearerAuth: "Bearer ");
var result = await sdk.Llm.Prompts.CreateAsync(
new CreatePromptRequest
{
Name = "greeting",
Description = "A simple greeting template",
Template = "Hello, {{name}}! Welcome to {{company}}.",
Metadata = new Dictionary { { "team", "onboarding" } },
}
);
Console.WriteLine(result.CreatePromptResponseValue!.Id); // prompt_abc123...
Console.WriteLine(result.CreatePromptResponseValue!.ActiveVersion); // 1
Console.WriteLine(result.CreatePromptResponseValue!.Version!.Version); // 1
```
```bash CLI theme={null}
mka1 llm prompts create \
--body '{
"name": "greeting",
"description": "A simple greeting template",
"template": "Hello, {{name}}! Welcome to {{company}}.",
"metadata": { "team": "onboarding" }
}' \
-H 'X-On-Behalf-Of: '
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/prompts \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"name": "greeting",
"description": "A simple greeting template",
"template": "Hello, {{name}}! Welcome to {{company}}.",
"metadata": { "team": "onboarding" }
}'
```
## Retrieve a prompt with rendered variables
Pass `variables` as a query parameter to render the template with your values.
Unmatched placeholders are left as-is.
Optionally, pass `version` to retrieve (and render) a specific version. If omitted,
the active version is returned.
The response always includes `active_template` (`activeTemplate` in the TypeScript SDK) — the raw
template text of the requested version, with `{{placeholders}}` intact. When you pass `variables`,
the response also includes `rendered_template` (`renderedTemplate`) with the substituted result;
it is absent when no variables are provided.
```ts TypeScript SDK theme={null}
const prompt = await sdk.llm.prompts.get({
xOnBehalfOf: '',
id: promptId,
variables: JSON.stringify({ name: 'Alice', company: 'Acme' }),
});
console.log(prompt.renderedTemplate);
// "Hello, Alice! Welcome to Acme."
```
```python Python SDK theme={null}
prompt = sdk.llm.prompts.get(
id=prompt_id,
variables='{"name": "Alice", "company": "Acme"}',
)
print(prompt.rendered_template)
# "Hello, Alice! Welcome to Acme."
```
```csharp C# SDK theme={null}
var prompt = await sdk.Llm.Prompts.GetAsync(
id: promptId,
variables: "{\"name\":\"Alice\",\"company\":\"Acme\"}"
);
Console.WriteLine(prompt.GetPromptResponseValue!.RenderedTemplate);
// "Hello, Alice! Welcome to Acme."
```
```bash CLI theme={null}
mka1 llm prompts get \
--id prompt_abc123 \
--variables '{"name":"Alice","company":"Acme"}'
```
```bash Bash theme={null}
# URL-encode the variables JSON
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123?variables=%7B%22name%22%3A%22Alice%22%2C%22company%22%3A%22Acme%22%7D" \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: '
```
## List prompts
Retrieve a paginated list of all prompts. Use `after` for cursor-based pagination.
```ts TypeScript SDK theme={null}
const list = await sdk.llm.prompts.list({
xOnBehalfOf: '',
limit: 10,
order: 'desc',
});
for (const prompt of list.data) {
console.log(prompt.name, `v${prompt.activeVersion}`);
}
if (list.hasMore) {
// Fetch next page using the last ID as cursor
const next = await sdk.llm.prompts.list({
xOnBehalfOf: '',
limit: 10,
after: list.lastId,
});
}
```
```python Python SDK theme={null}
prompts = sdk.llm.prompts.list()
for prompt in prompts.data:
print(prompt.name, f"v{prompt.active_version}")
```
```csharp C# SDK theme={null}
var prompts = await sdk.Llm.Prompts.ListAsync();
Console.WriteLine(prompts);
```
```bash CLI theme={null}
mka1 llm prompts list --limit 10 --order desc
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/llm/prompts?limit=10&order=desc" \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: '
```
## Update prompt metadata
Update the name, description, or metadata of a prompt. To change the template,
create a new version instead.
Note: `metadata` replaces the existing metadata object (it is not merged). To clear a description, pass `null`.
```ts TypeScript SDK theme={null}
const updated = await sdk.llm.prompts.update({
xOnBehalfOf: '',
id: promptId,
requestBody: {
name: 'welcome-greeting',
description: 'Updated greeting for the welcome flow',
metadata: { team: 'onboarding', reviewed: true },
},
});
```
```python Python SDK theme={null}
updated = sdk.llm.prompts.update(
id=prompt_id,
name="welcome-greeting",
description="Updated greeting for the welcome flow",
metadata={"team": "onboarding", "reviewed": True},
)
```
```csharp C# SDK theme={null}
var updated = await sdk.Llm.Prompts.UpdateAsync(
id: promptId,
body: new UpdatePromptRequestBody
{
Name = "welcome-greeting",
Description = "Updated greeting for the welcome flow",
Metadata = new Dictionary
{
{ "team", "onboarding" },
{ "reviewed", true },
},
}
);
```
```bash CLI theme={null}
mka1 llm prompts update \
--id prompt_abc123 \
--body '{
"name": "welcome-greeting",
"description": "Updated greeting for the welcome flow",
"metadata": { "team": "onboarding", "reviewed": true }
}'
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123" \
--request PUT \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"name": "welcome-greeting",
"description": "Updated greeting for the welcome flow",
"metadata": { "team": "onboarding", "reviewed": true }
}'
```
## Create a new version
Each template change creates a new version. The new version automatically becomes the active version.
```ts TypeScript SDK theme={null}
const version = await sdk.llm.prompts.createVersion({
xOnBehalfOf: '',
id: promptId,
requestBody: {
template: 'Hi {{name}}! Welcome aboard at {{company}}. Your onboarding starts {{date}}.',
},
});
console.log(version.version); // 2
console.log(version.template); // The new template text
```
```python Python SDK theme={null}
version = sdk.llm.prompts.create_version(
id=prompt_id,
template="Hi {{name}}! Welcome aboard at {{company}}. Your onboarding starts {{date}}.",
)
print(version.version) # 2
print(version.template) # The new template text
```
```csharp C# SDK theme={null}
var version = await sdk.Llm.Prompts.CreateVersionAsync(
id: promptId,
body: new CreatePromptVersionRequestBody
{
Template = "Hi {{name}}! Welcome aboard at {{company}}. Your onboarding starts {{date}}.",
}
);
Console.WriteLine(version.CreateVersionResponse!.Version); // 2
Console.WriteLine(version.CreateVersionResponse!.Template); // The new template text
```
```bash CLI theme={null}
mka1 llm prompts create-version \
--id prompt_abc123 \
--body '{
"template": "Hi {{name}}! Welcome aboard at {{company}}. Your onboarding starts {{date}}."
}'
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123/versions" \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"template": "Hi {{name}}! Welcome aboard at {{company}}. Your onboarding starts {{date}}."
}'
```
## View version history
List all versions of a prompt to see its full change history.
```ts TypeScript SDK theme={null}
const versions = await sdk.llm.prompts.listVersions({
xOnBehalfOf: '',
id: promptId,
order: 'desc',
});
for (const v of versions.data) {
console.log(`v${v.version}: ${v.template.slice(0, 50)}...`);
}
```
```python Python SDK theme={null}
versions = sdk.llm.prompts.list_versions(id=prompt_id)
for v in versions.data:
print(f"v{v.version}: {v.template[:50]}...")
```
```csharp C# SDK theme={null}
var versions = await sdk.Llm.Prompts.ListVersionsAsync(
id: promptId,
order: ListPromptVersionsOrder.Desc
);
foreach (var v in versions.ListVersionsResponse!.Data)
{
Console.WriteLine($"v{v.Version}: {v.Template.Substring(0, 50)}...");
}
```
```bash CLI theme={null}
mka1 llm prompts list-versions --id prompt_abc123 --order desc
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123/versions?order=desc" \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: '
```
## Retrieve a specific version
Fetch a single version by its version number.
```ts TypeScript SDK theme={null}
const v1 = await sdk.llm.prompts.getVersion({
xOnBehalfOf: '',
id: promptId,
version: 1,
});
console.log(v1.template);
```
```python Python SDK theme={null}
v1 = sdk.llm.prompts.get_version(id=prompt_id, version=1)
print(v1.template)
```
```csharp C# SDK theme={null}
var v1 = await sdk.Llm.Prompts.GetVersionAsync(
id: promptId,
version: 1
);
Console.WriteLine(v1.CreateVersionResponse!.Template);
```
```bash CLI theme={null}
mka1 llm prompts get-version --id prompt_abc123 --version-param 1
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123/versions/1" \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: '
```
## Roll back to a previous version
Rollback sets an earlier version as the active version. All versions are preserved — rollback
does not delete newer versions, so you can always roll forward again.
```ts TypeScript SDK theme={null}
// Currently on version 2, roll back to version 1
const rolledBack = await sdk.llm.prompts.rollback({
xOnBehalfOf: '',
id: promptId,
requestBody: {
version: 1,
},
});
console.log(rolledBack.activeVersion); // 1
console.log(rolledBack.latestVersion); // 2 (still exists)
```
```python Python SDK theme={null}
# Currently on version 2, roll back to version 1
rolled_back = sdk.llm.prompts.rollback(id=prompt_id, version=1)
print(rolled_back.active_version) # 1
print(rolled_back.latest_version) # 2 (still exists)
```
```csharp C# SDK theme={null}
// Currently on version 2, roll back to version 1
var rolledBack = await sdk.Llm.Prompts.RollbackAsync(
id: promptId,
body: new RollbackPromptRequestBody { Version = 1 }
);
Console.WriteLine(rolledBack.UpdatePromptResponse!.ActiveVersion); // 1
Console.WriteLine(rolledBack.UpdatePromptResponse!.LatestVersion); // 2 (still exists)
```
```bash CLI theme={null}
# Currently on version 2, roll back to version 1
mka1 llm prompts rollback --id prompt_abc123 --version-param 1
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123/rollback" \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{ "version": 1 }'
```
## Delete a prompt
Deleting a prompt removes it and all of its versions permanently.
```ts TypeScript SDK theme={null}
const deleted = await sdk.llm.prompts.delete({
xOnBehalfOf: '',
id: promptId,
});
console.log(deleted.deleted); // true
```
```python Python SDK theme={null}
deleted = sdk.llm.prompts.delete(id=prompt_id)
print(deleted.deleted) # True
```
```csharp C# SDK theme={null}
var deleted = await sdk.Llm.Prompts.DeleteAsync(id: promptId);
Console.WriteLine(deleted.DeletePromptResponseValue!.Deleted); // True
```
```bash CLI theme={null}
mka1 llm prompts delete --id prompt_abc123
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123" \
--request DELETE \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: '
```
## Full example: versioning and rollback workflow
This example demonstrates the complete lifecycle — creating a prompt, iterating on the
template, reviewing history, and rolling back.
```ts TypeScript SDK theme={null}
// 1. Create a prompt with the initial template
const prompt = await sdk.llm.prompts.create({
xOnBehalfOf: 'user-123',
createPromptRequest: {
name: 'support-reply',
template: 'Hi {{customer}}, thanks for contacting us about {{issue}}.',
},
});
console.log('Created:', prompt.id, 'v1');
// 2. Ship v2 with a friendlier tone
const v2 = await sdk.llm.prompts.createVersion({
xOnBehalfOf: 'user-123',
id: prompt.id,
requestBody: {
template: 'Hey {{customer}}! We got your message about {{issue}} and are on it.',
},
});
console.log('Created v2:', v2.version);
// 3. Retrieve the prompt — active version is now v2
const current = await sdk.llm.prompts.get({
xOnBehalfOf: 'user-123',
id: prompt.id,
variables: JSON.stringify({ customer: 'Alice', issue: 'billing' }),
});
console.log('Active:', current.renderedTemplate);
// "Hey Alice! We got your message about billing and are on it."
// 4. Review version history
const history = await sdk.llm.prompts.listVersions({
xOnBehalfOf: 'user-123',
id: prompt.id,
order: 'asc',
});
for (const v of history.data) {
console.log(` v${v.version}: ${v.template}`);
}
// 5. Roll back to v1
const rolledBack = await sdk.llm.prompts.rollback({
xOnBehalfOf: 'user-123',
id: prompt.id,
requestBody: {
version: 1,
},
});
console.log('Rolled back to v' + rolledBack.activeVersion);
// activeVersion=1, latestVersion=2
// 6. Clean up
await sdk.llm.prompts.delete({ xOnBehalfOf: 'user-123', id: prompt.id });
```
```python Python SDK theme={null}
# 1. Create a prompt with the initial template
prompt = sdk.llm.prompts.create(
name="support-reply",
template="Hi {{customer}}, thanks for contacting us about {{issue}}.",
)
print("Created:", prompt.id, "v1")
# 2. Ship v2 with a friendlier tone
v2 = sdk.llm.prompts.create_version(
id=prompt.id,
template="Hey {{customer}}! We got your message about {{issue}} and are on it.",
)
print("Created v2:", v2.version)
# 3. Retrieve the prompt — active version is now v2
current = sdk.llm.prompts.get(
id=prompt.id,
variables='{"customer": "Alice", "issue": "billing"}',
)
print("Active:", current.rendered_template)
# "Hey Alice! We got your message about billing and are on it."
# 4. Review version history
history = sdk.llm.prompts.list_versions(id=prompt.id)
for v in history.data:
print(f" v{v.version}: {v.template}")
# 5. Roll back to v1
rolled_back = sdk.llm.prompts.rollback(id=prompt.id, version=1)
print("Rolled back to v" + str(rolled_back.active_version))
# active_version=1, latest_version=2
# 6. Clean up
sdk.llm.prompts.delete(id=prompt.id)
```
```csharp C# SDK theme={null}
// 1. Create a prompt with the initial template
var prompt = await sdk.Llm.Prompts.CreateAsync(
new CreatePromptRequest
{
Name = "support-reply",
Template = "Hi {{customer}}, thanks for contacting us about {{issue}}.",
}
);
var promptId = prompt.CreatePromptResponseValue!.Id;
Console.WriteLine($"Created: {promptId} v1");
// 2. Ship v2 with a friendlier tone
var v2 = await sdk.Llm.Prompts.CreateVersionAsync(
id: promptId,
body: new CreatePromptVersionRequestBody
{
Template = "Hey {{customer}}! We got your message about {{issue}} and are on it.",
}
);
Console.WriteLine($"Created v2: {v2.CreateVersionResponse!.Version}");
// 3. Retrieve the prompt with rendered variables
var current = await sdk.Llm.Prompts.GetAsync(
id: promptId,
variables: "{\"customer\":\"Alice\",\"issue\":\"billing\"}"
);
Console.WriteLine($"Active: {current.GetPromptResponseValue!.RenderedTemplate}");
// 4. Review version history
var history = await sdk.Llm.Prompts.ListVersionsAsync(
id: promptId,
order: ListPromptVersionsOrder.Asc
);
foreach (var v in history.ListVersionsResponse!.Data)
{
Console.WriteLine($" v{v.Version}: {v.Template}");
}
// 5. Roll back to v1
var rolledBack = await sdk.Llm.Prompts.RollbackAsync(
id: promptId,
body: new RollbackPromptRequestBody { Version = 1 }
);
Console.WriteLine($"Rolled back to v{rolledBack.UpdatePromptResponse!.ActiveVersion}");
// 6. Clean up
await sdk.Llm.Prompts.DeleteAsync(id: promptId);
```
```bash CLI theme={null}
# 1. Create a prompt with the initial template
mka1 llm prompts create \
--body '{
"name": "support-reply",
"template": "Hi {{customer}}, thanks for contacting us about {{issue}}."
}'
# → { "id": "prompt_abc123", "active_version": 1, "version": { "version": 1, ... }, ... }
# 2. Ship v2 with a friendlier tone
mka1 llm prompts create-version \
--id prompt_abc123 \
--body '{
"template": "Hey {{customer}}! We got your message about {{issue}} and are on it."
}'
# 3. Retrieve the prompt with rendered variables
mka1 llm prompts get \
--id prompt_abc123 \
--variables '{"customer":"Alice","issue":"billing"}'
# 4. Review version history
mka1 llm prompts list-versions --id prompt_abc123 --order asc
# 5. Roll back to v1
mka1 llm prompts rollback --id prompt_abc123 --version-param 1
# 6. Clean up
mka1 llm prompts delete --id prompt_abc123
```
```bash Bash theme={null}
# 1. Create a prompt
curl https://apigw.mka1.com/api/v1/llm/prompts \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: user-123' \
--data '{
"name": "support-reply",
"template": "Hi {{customer}}, thanks for contacting us about {{issue}}."
}'
# → { "id": "prompt_abc123", "active_version": 1, "version": { "version": 1, ... }, ... }
# 2. Create v2 with a friendlier tone
curl https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123/versions \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: user-123' \
--data '{
"template": "Hey {{customer}}! We got your message about {{issue}} and are on it."
}'
# 3. Get the prompt with rendered variables
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123?variables=%7B%22customer%22%3A%22Alice%22%2C%22issue%22%3A%22billing%22%7D" \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: user-123'
# 4. View version history
curl "https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123/versions?order=asc" \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: user-123'
# 5. Roll back to v1
curl https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123/rollback \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: user-123' \
--data '{ "version": 1 }'
# 6. Delete the prompt
curl https://apigw.mka1.com/api/v1/llm/prompts/prompt_abc123 \
--request DELETE \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: user-123'
```
## Behavior details
| Aspect | Detail |
| - | - |
| Versioning | Immutable — each template change creates a new version that cannot be modified |
| Active version | New versions auto-activate; use rollback to switch to a different version |
| Rollback | Non-destructive — sets `active_version` without deleting newer versions |
| Pagination | Cursor-based for listing prompts — use `after` parameter with `last_id` from response |
| Template rendering | Server-side — pass `variables` query parameter; unmatched placeholders preserved |
| Ownership | Per API key — prompts are isolated by authentication context |
| Concurrency | Conflict detection — concurrent version creation returns 409 |
## Next steps
* [Generate a response](/docs/generate-a-response) — use rendered prompts as input to the Responses API
* [Structured data](/docs/extract-structured-data) — combine prompts with structured extraction
* [Conversations](/docs/conversations) — manage multi-turn exchanges with versioned system prompts
# Quickstart
Source: https://docs.mka1.com/docs/quickstart
Make your first MKA1 API request with an API key and SDK.
Start with an MKA1 API key and your deployment’s API gateway URL. If you need a key, see [API keys](/docs/authentication). You do not need to create an organization or configure resource permissions to use a key your administrator has already provided.
## Install a client
```bash TypeScript theme={null}
npm install @meetkai/mka1
```
```bash OpenAI theme={null}
npm install openai
```
```bash Python theme={null}
pip install meetkai-mka1
```
```bash C# theme={null}
dotnet add package MeetKai.MKA1
```
For the command line, follow [CLI installation](/docs/cli/introduction) and [authentication](/docs/cli/authentication).
## Choose your endpoint
The hosted API uses `https://apigw.mka1.com`. For a private deployment, use the gateway URL supplied by your administrator. See [SDKs](/docs/sdks) for each client’s server URL option. The model `auto` must resolve to an active model in your organization; see [Models](/docs/models).
## Send your first request
Pass a string in `input` for a single-turn request.
The response includes generated text in `output_text`.
If a guardrail blocks the request, `output_text` is absent and the output carries a refusal instead; see [Guardrails](/docs/guardrails#detect-a-block-in-code).
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const result = await sdk.llm.responses.create({
xOnBehalfOf: '', // optional — attribute the request to one of your end users
responsesCreateRequest: {
model: 'auto',
input: 'Write a one-sentence summary of the MKA1 API.',
},
});
```
```ts OpenAI SDK theme={null}
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: '',
baseURL: 'https://apigw.mka1.com/api/v1/llm/',
defaultHeaders: { 'X-On-Behalf-Of': '' },
});
const response = await openai.responses.create({
model: 'auto',
input: 'Write a one-sentence summary of the MKA1 API.',
stream: false,
});
```
```python Python SDK theme={null}
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
res = sdk.llm.responses.create(
model="auto",
input="Write a one-sentence summary of the MKA1 API.",
x_on_behalf_of="", # optional — attribute the request to one of your end users
)
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Components;
using MeetKai.MKA1.Types.Requests;
var sdk = new SDK(bearerAuth: "Bearer ");
var res = await sdk.Llm.Responses.CreateAsync(new ResponsesCreateRequest()
{
Model = "auto",
Input = ResponsesCreateRequestInput.CreateStr(
"Write a one-sentence summary of the MKA1 API."),
});
```
```bash CLI theme={null}
mka1 llm responses create \
--model auto \
--input '"Write a one-sentence summary of the MKA1 API."' \
-H 'X-On-Behalf-Of: '
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"model": "auto",
"input": "Write a one-sentence summary of the MKA1 API."
}'
```
If you are not acting for an end user, omit `X-On-Behalf-Of`.
## Read the result
A successful response contains an ID and generated output. Look for `output_text` in the wire response (`outputText` in the TypeScript SDK). A guardrail refusal is a different output item, so do not assume every successful HTTP request contains text.
## Next steps
* [Text generation](/docs/generate-a-response): instructions, messages, and generation settings.
* [Streaming](/docs/streaming): display text as it arrives.
* [Create and run agents](/docs/managing-agents): save reusable model and tool configurations.
# Rate limits
Source: https://docs.mka1.com/docs/rate-limiting
Per-key rate limits with configurable quotas per minute, hour, or day. Includes real HTTP 429 demonstration and retry patterns.
The MKA1 API enforces rate limits on a **per-key basis**.
Each API key has its own quota configured independently — requests per minute, hour, or day.
When a key exceeds its limit, the gateway returns `429 Too Many Requests` before the request reaches the model. No tokens are consumed and no usage is billed.
## Rate limit configuration
Rate limits are set per API key at provisioning time. The available granularities are:
| Window | Example |
| - | - |
| Per minute | 60 requests/minute |
| Per hour | 1,000 requests/hour |
| Per day | 10,000 requests/day |
Each rate-limit configuration holds a single window and maximum — one key cannot combine multiple windows (for example, a per-minute **and** a per-hour cap on the same key is not supported). Limits stack only across levels: an org-level rate limit (set via `PATCH /api/v1/authentication/orgs/{orgId}/rate-limit`) and a key-level limit can both apply to the same request.
## Demonstration: rate limiting in action
The following example uses a real API key configured with a rate limit of **1 request per minute**. The first request succeeds, and the second request — sent immediately after — is rejected with HTTP 429.
### Request 1 — succeeds
```bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"model": "auto",
"input": "Hello, how are you?",
"stream": false
}'
```
**Response: HTTP 200**
```json theme={null}
{
"id": "resp_5ab19d58984940c88a971c6829ae201c",
"object": "response",
"status": "completed",
"model": "auto",
"output": [
{
"type": "message",
"role": "assistant",
"content": [{ "type": "output_text", "text": "Hello! I'm doing well..." }]
}
]
}
```
### Request 2 — rate limited (sent immediately after)
```bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"model": "auto",
"input": "This should be rate limited",
"stream": false
}'
```
**Response: HTTP 429**
```json theme={null}
{
"error": "Rate limit exceeded"
}
```
The gateway rejects the request before it reaches the model — no tokens are consumed and no usage is billed.
### Programmatic example
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
import { APIError } from '@meetkai/mka1/models/errors';
import type { ResponseObject } from '@meetkai/mka1/models/components';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
// First request — succeeds
const response = await sdk.llm.responses.create({
responsesCreateRequest: {
model: 'auto',
input: 'Hello',
},
}) as ResponseObject;
console.log(response.status); // "completed"
// Second request — rate limited
try {
await sdk.llm.responses.create({
responsesCreateRequest: {
model: 'auto',
input: 'This will be rate limited',
},
});
} catch (err) {
if (err instanceof APIError && err.statusCode === 429) {
console.log(err.statusCode); // 429
console.log(err.body); // '{"error":"Rate limit exceeded"}'
}
}
```
```ts OpenAI SDK theme={null}
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: '',
baseURL: 'https://apigw.mka1.com/api/v1/llm/',
defaultHeaders: { 'X-On-Behalf-Of': '' },
});
// First request — succeeds
const response = await openai.responses.create({
model: 'auto',
input: 'Hello',
stream: false,
});
console.log(response.status); // "completed"
// Second request — rate limited
try {
await openai.responses.create({
model: 'auto',
input: 'This will be rate limited',
stream: false,
});
} catch (err) {
if (err instanceof OpenAI.RateLimitError) {
console.log(err.status); // 429
console.log(err.message); // "429 Rate limit exceeded"
console.log(err.error); // { error: "Rate limit exceeded" }
}
}
```
```python Python SDK theme={null}
import time
from meetkai_mka1 import SDK
from meetkai_mka1.errors import SDKDefaultError
sdk = SDK(bearer_auth="Bearer ")
try:
res = sdk.llm.responses.create(
model="auto",
input="Summarize this document.",
)
except SDKDefaultError as e:
if e.status_code == 429:
time.sleep(int(e.headers.get("retry-after", 1)))
res = sdk.llm.responses.create(
model="auto",
input="Summarize this document.",
)
else:
raise
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Components;
using MeetKai.MKA1.Types.Errors;
var sdk = new SDK(bearerAuth: "Bearer ");
// First request — succeeds
var response = await sdk.Llm.Responses.CreateAsync(new ResponsesCreateRequest()
{
Model = "auto",
Input = ResponsesCreateRequestInput.CreateStr("Hello"),
});
// Second request — may be rate limited
try
{
await sdk.Llm.Responses.CreateAsync(new ResponsesCreateRequest()
{
Model = "auto",
Input = ResponsesCreateRequestInput.CreateStr("This will be rate limited"),
});
}
catch (APIException ex) when ((int)ex.Response.StatusCode == 429)
{
Console.WriteLine(ex.Response.StatusCode); // TooManyRequests
Console.WriteLine(ex.Body); // "Rate limit exceeded"
}
```
```bash CLI theme={null}
# First request — succeeds (HTTP 200)
mka1 llm responses create \
--model auto \
--input '"Hello"' \
--include-headers \
-H 'X-On-Behalf-Of: '
# Second request — rate limited (HTTP 429)
mka1 llm responses create \
--model auto \
--input '"This will be rate limited"' \
--include-headers \
-H 'X-On-Behalf-Of: '
```
```bash Bash theme={null}
# First request — succeeds (HTTP 200)
curl -s -w "\nHTTP %{http_code}" https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{ "model": "auto", "input": "Hello", "stream": false }'
# Second request — rate limited (HTTP 429)
curl -s -w "\nHTTP %{http_code}" https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{ "model": "auto", "input": "This will be rate limited", "stream": false }'
```
## The 429 response
When a request is rate limited, the gateway returns:
| Field | Value |
| - | - |
| **HTTP status** | `429 Too Many Requests` |
| **Content-Type** | `application/json` |
| **Body** | `{"error": "Rate limit exceeded"}` |
| **Tokens consumed** | 0 — the request never reaches the model |
| **Usage billed** | None |
The OpenAI SDK surfaces this as an `OpenAI.RateLimitError` with `err.status === 429`.
The TypeScript SDK throws an `APIError` with `err.statusCode === 429`.
## Handling rate limits in your application
When your application receives a 429 response, retry with exponential backoff:
```ts OpenAI SDK theme={null}
async function requestWithRetry(fn: () => Promise, maxRetries = 3): Promise {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (err: any) {
if (err.status === 429 && attempt < maxRetries - 1) {
const waitMs = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await new Promise((r) => setTimeout(r, waitMs));
continue;
}
throw err;
}
}
}
const response = await requestWithRetry(() =>
openai.responses.create({ model: 'auto', input: 'Hello', stream: false })
);
```
## See also
* [Authentication](/docs/authentication) for API key setup and the `X-On-Behalf-Of` pattern.
* [Authorization](/docs/authorization) for resource-level access control.
* [Budgets](/docs/budgets) for spend caps per organization, member, team, API key, or end user; a block returns `403`, not `429`.
* [Generate a response](/docs/generate-a-response) for the base Responses request shape.
# Repositories
Source: https://docs.mka1.com/docs/repositories
Early access
Create and manage mka1-repos repositories — org-scoped git repositories for the model weights and datasets that Compute workloads pull from and publish to.
mka1-repos is the platform's repository service for model weights and datasets.
Every repository is an ordinary git repository with Git LFS, owned by exactly one organization and identified by the pair `/` — for example `meetkai/functionary`.
That identifier is the whole point.
You push artifacts to the repository from your machine over git, and Compute workloads resolve the same `/` through the platform's Hugging Face-compatible artifact endpoint to train on or serve them.
This guide covers both halves: the management API for creating, listing, renaming and deleting repositories, and the two client tools — `git` and the Hugging Face CLI — that move bytes in and out.
The CLI examples assume an [authenticated MKA1 CLI](/docs/cli/authentication).
## Before you start
You need:
| Requirement | Notes |
| - | - |
| API key | Send it as `Authorization: Bearer ` on every request. |
| Org owner or admin role | Every repository endpoint is restricted to owners and admins of the organization. There are no per-repository permissions; access is decided by your org role alone. |
| `git` and `git-lfs` | Model weights are large binaries; the git host stores them through Git LFS, so install and initialize `git lfs` before the first push. |
Repositories always belong to the caller's organization.
You never choose the `org` at create time — it is derived from your API key — and you cannot reach another organization's repositories at all.
## Create a repository
Pick a name and optionally a description.
The name must start with a letter or digit and be at most 100 characters of letters, digits, dots, underscores, and dashes (`^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$`).
Optionally, set `kind` to declare what the repository will hold. If omitted, it defaults to `repo`.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const result = await sdk.repos.create({
"createRepoRequest": {
"name": "functionary",
"description": "Fine-tuned weights for the MeetKai assistant."
}
});
console.log(result.id);
```
```python Python SDK theme={null}
import os
from meetkai_mka1 import models
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
result = sdk.repos.create(
name="functionary",
description="Fine-tuned weights for the MeetKai assistant.",
)
print(result.id)
```
```csharp C# SDK theme={null}
using MeetKai.MKA1.Types.Components;
using MeetKai.MKA1.Types.Requests;
using Newtonsoft.Json;
using MeetKai.MKA1;
var sdk = new SDK(bearerAuth: "Bearer ");
// Deserialize the wire-format payload into the SDK request model.
var body = JsonConvert.DeserializeObject ("""
{
"name": "functionary",
"description": "Fine-tuned weights for the MeetKai assistant."
}
""")!;
var response = await sdk.Repos.CreateAsync(body);
var result = response.Repo
?? throw new InvalidOperationException(JsonConvert.SerializeObject(response));
Console.WriteLine(JsonConvert.SerializeObject(result.Id));
```
```bash CLI theme={null}
mka1 repos create \
--output-format json \
--body @- <<'JSON'
{
"description": "Fine-tuned weights for the MeetKai assistant.",
"name": "functionary"
}
JSON
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/repos \
--request POST \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $MKA1_API_KEY" \
--data '{
"name": "functionary",
"description": "Fine-tuned weights for the MeetKai assistant."
}'
```
The response is `201` with the repository:
```json theme={null}
{
"id": "rqz4h6k2m5n7p9r3t5v7w9x2",
"org": "meetkai",
"name": "functionary",
"description": "Fine-tuned weights for the MeetKai assistant.",
"created_at": "2026-07-30T09:15:00Z"
}
```
`id` is an opaque, stable identifier — the canonical key that survives renames.
`org` and `name` are the user-facing labels that form the repository reference and its URLs.
Creation provisions the backing git repository as part of the request.
If that provisioning fails, the create returns `502 provision_failed`. The rollback is best-effort, so retrying the same name may return `409 name_taken`; if it does, delete the repository and try again.
The request body rejects unknown fields, and a name that is already taken in your org returns `409`.
## The repository reference and git URL
Two values identify a repository everywhere else on the platform:
| Value | Shape | Used for |
| - | - | - |
| Repository reference | `/`, e.g. `meetkai/functionary` | Hugging Face-compatible resolution inside Compute workloads, and tools like ms-swift and vLLM. |
| Git URL | `https://git.mka1.com//.git` | `git clone`, `git push`, and Git LFS transfers from your own machines. |
The git host authenticates with HTTP basic auth: the username must be your org slug and the password is an MKA1 API key. `org:apikey` is enforced — a username that does not match the organization is rejected.
Both values are what you hand to a Compute workload as environment variables — see [Run a fine-tune job](/docs/compute-fine-tune-job) and [Deploy a model server](/docs/compute-deployment).
## List repositories
Returns every repository in your organization.
You can optionally filter by `kind`. Note that legacy untyped repositories (`kind: null`) only appear when you omit the filter.
```ts TypeScript SDK theme={null}
const result = await sdk.repos.list({});
console.log(result.repos);
```
```python Python SDK theme={null}
result = sdk.repos.list()
print(result.repos)
```
```csharp C# SDK theme={null}
var response = await sdk.Repos.ListAsync();
var result = response.Object
?? throw new InvalidOperationException(JsonConvert.SerializeObject(response));
Console.WriteLine(JsonConvert.SerializeObject(result.Repos));
```
```bash CLI theme={null}
mka1 repos list \
--output-format json
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/repos \
--header "Authorization: Bearer $MKA1_API_KEY"
```
```json theme={null}
{
"repos": [
{
"id": "rqz4h6k2m5n7p9r3t5v7w9x2",
"org": "meetkai",
"name": "functionary",
"description": "Fine-tuned weights for the MeetKai assistant.",
"created_at": "2026-07-30T09:15:00Z"
},
{
"id": "rb8s2d4f6h8j1l3n5q7s9v2x",
"org": "meetkai",
"name": "support-conversations",
"description": "Curated support transcripts for fine-tuning.",
"created_at": "2026-07-28T16:40:00Z"
}
]
}
```
## Get a repository
Read a single repository by its reference.
```ts TypeScript SDK theme={null}
const result = await sdk.repos.get({
"org": "meetkai",
"name": "functionary"
});
console.log(result.description);
```
```python Python SDK theme={null}
result = sdk.repos.get(
org="meetkai",
name="functionary",
)
print(result.description)
```
```csharp C# SDK theme={null}
var response = await sdk.Repos.GetAsync("meetkai", "functionary");
var result = response.Repo
?? throw new InvalidOperationException(JsonConvert.SerializeObject(response));
Console.WriteLine(JsonConvert.SerializeObject(result.Description));
```
```bash CLI theme={null}
mka1 repos get \
--org meetkai \
--name functionary \
--output-format json
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/repos/meetkai/functionary \
--header "Authorization: Bearer $MKA1_API_KEY"
```
A repository that does not exist in your org returns `404` — including any repository that belongs to a different org.
## Rename or update a repository
Updates are label-only: you can change `name`, `description`, and `kind`, and an omitted field is left unchanged.
```ts TypeScript SDK theme={null}
const result = await sdk.repos.update({
"org": "meetkai",
"name": "functionary",
"patchRepoRequest": {
"name": "functionary-v2"
}
});
console.log(result.name);
```
```python Python SDK theme={null}
result = sdk.repos.update(
org="meetkai",
name_param="functionary",
name="functionary-v2",
)
print(result.name)
```
```csharp C# SDK theme={null}
// Deserialize the wire-format payload into the SDK request model.
var body = JsonConvert.DeserializeObject ("""
{
"name": "functionary-v2"
}
""")!;
var response = await sdk.Repos.UpdateAsync("meetkai", "functionary", body);
var result = response.Repo
?? throw new InvalidOperationException(JsonConvert.SerializeObject(response));
Console.WriteLine(JsonConvert.SerializeObject(result.Name));
```
```bash CLI theme={null}
mka1 repos update \
--org meetkai \
--name functionary \
--output-format json \
--body @- <<'JSON'
{
"name": "functionary-v2"
}
JSON
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/repos/meetkai/functionary \
--request PATCH \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $MKA1_API_KEY" \
--data '{"name": "functionary-v2"}'
```
The repository `id` is stable, so a rename is a metadata update — the git history and stored artifacts are untouched.
Renaming to a name that already exists in your org returns `409`.
Changing `kind` may be refused with `409 kind_has_content` if the repository still has container images reachable by tags (for example, switching away from `image`, or typing a legacy `kind: null` repository as a non-image kind). If you hit this, list the tags and delete them first.
**A rename changes the repository reference and the git URL.**
The old `/` stops resolving immediately.
Update every git remote, every `REPO`/`REPO_URL` environment value in Compute create bodies, and every training or serving script that referenced the old name.
## List and delete image tags
If a repository holds container images, you can list and delete its tags through the management API.
The listing is a fact about what the repository currently holds (it is not derived from `kind`): a repository of any kind may list `[]`, and a legacy `kind: null` repository that still holds images lists the tags it has.
List tags:
```bash theme={null}
curl https://apigw.mka1.com/api/v1/repos/meetkai/functionary/tags \
--header "Authorization: Bearer $MKA1_API_KEY"
```
The response is a single page (up to 1000 tags) and includes a `truncated` flag:
```json theme={null}
{
"tags": [
{
"tag": "latest",
"digest": "sha256:...",
"media_type": "application/vnd.oci.image.manifest.v1+json",
"size": 123456789,
"moved_at": "2026-07-30T09:15:00Z"
}
],
"truncated": false
}
```
Delete a single tag:
```bash theme={null}
curl https://apigw.mka1.com/api/v1/repos/meetkai/functionary/tags/latest \
--request DELETE \
--header "Authorization: Bearer $MKA1_API_KEY"
```
Deleting a tag is an *untag*: it removes the name, but the underlying image may remain reachable by digest and by any other tag that points to it.
If the repository does not exist (or exists outside your org), deletion returns `404 not_found`. If the repository exists but the tag does not, deletion returns `404 tag_not_found`.
## Delete a repository
```ts TypeScript SDK theme={null}
const result = await sdk.repos.delete({
"org": "meetkai",
"name": "functionary"
});
console.log('Request completed');
```
```python Python SDK theme={null}
result = sdk.repos.delete(
org="meetkai",
name="functionary",
)
print("Request completed")
```
```csharp C# SDK theme={null}
var response = await sdk.Repos.DeleteAsync("meetkai", "functionary");
Console.WriteLine("Request completed");
```
```bash CLI theme={null}
mka1 repos delete \
--org meetkai \
--name functionary \
--output-format json
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/repos/meetkai/functionary \
--request DELETE \
--header "Authorization: Bearer $MKA1_API_KEY"
```
The response is `204` with no body.
The repository record is removed immediately — that delete is authoritative — while teardown of the backing git storage is best-effort cleanup.
A repeated delete of the same reference returns `404`.
Deleting a repository removes the repository, its git history, and every stored artifact.
This cannot be undone — there is no soft delete and no recovery window.
## Push and pull with git
Clone the repository, or add it as a remote of an existing local repository:
```bash theme={null}
git clone https://git.mka1.com/meetkai/functionary-train-data.git
cd functionary-train-data
```
```bash theme={null}
# In an existing local repository instead:
git remote add mka1 https://git.mka1.com/meetkai/functionary-train-data.git
```
Track large binaries with Git LFS before committing them.
Weight files must go through LFS; small text files such as configs, tokenizer definitions, and JSONL datasets can stay in plain git.
```bash theme={null}
git lfs install
git lfs track "*.safetensors" "*.bin" "*.gguf"
git add .gitattributes
```
Then commit and push as usual:
```bash theme={null}
git add .
git commit -m "Add curated support transcripts"
git push origin main # or: git push mka1 main
```
Git authenticates the push with HTTP basic auth.
The username must be your org slug and the password is an MKA1 API key — `org:apikey` is enforced, so a username that does not match the organization is rejected:
```text theme={null}
Username for 'https://git.mka1.com': meetkai
Password for 'https://meetkai@git.mka1.com':
```
For non-interactive pushes (CI, a training box), export the API key as `MK_API_KEY` in the environment (for example from a CI secret) and supply it through a git credential helper, instead of embedding the key in the remote URL, where it would be written to `.git/config`:
```bash theme={null}
git config credential.helper '!f() { echo "username=meetkai"; echo "password=$MK_API_KEY"; }; f'
```
Lay out the repository however your training or serving stack expects.
The examples in this guide use two repositories: `meetkai/functionary-train-data`, a dataset repository holding JSONL transcripts, and `meetkai/functionary`, a weights repository in the usual Hugging Face layout (`config.json`, tokenizer files, `*.safetensors`).
## Push and pull with the Hugging Face CLI
Install the CLI with `uv tool install huggingface-hub==0.34.4` if `hf` is not already available.
The same repository is reachable over the Hugging Face Hub API. Set the endpoint and token, and disable Xet so uploads use the standard Hub/LFS path supported by mka1-repos:
```bash theme={null}
export HF_ENDPOINT=https://hf.mka1.com
export HF_TOKEN="$MKA1_API_KEY"
export HF_HUB_DISABLE_XET=1
```
With those set, the ordinary Hugging Face commands operate on your repositories instead of the public hub:
```bash theme={null}
hf download meetkai/functionary --local-dir ./base
hf download meetkai/functionary-train-data --repo-type dataset --local-dir ./data
hf upload meetkai/functionary ./merged .
```
The same variables work from Python, because `huggingface_hub` reads them by name:
```python theme={null}
from huggingface_hub import snapshot_download
path = snapshot_download(repo_id="meetkai/functionary")
```
`hf` is the current CLI; older environments ship the same commands as `huggingface-cli`.
Unlike git, this path does not need your org slug as a username — the token carries the identity.
This is the part that carries over to Compute. A training or serving container sets the same variables, and ms-swift or vLLM resolves `/` with no code changes — see [Run a fine-tune job](/docs/compute-fine-tune-job) and [Deploy a model server](/docs/compute-deployment).
## Errors
Repository endpoints return a uniform envelope with a stable machine-readable code and the request's correlation id:
```json theme={null}
{
"error": "not_found",
"correlation_id": "c0a8f3d2-4b6e-4f1a-9c7d-2e5b8a1f6d3c"
}
```
| Status | Code | Meaning |
| - | - | - |
| `400` | `invalid_name`, `invalid_body` | A name that violates the pattern, or a malformed body or unknown field (bodies reject unknown properties). |
| `401` | `unauthorized` | Missing or incomplete org-scoped identity on the request. |
| `403` | `forbidden` | The caller is not an owner or admin of the organization. |
| `404` | `not_found` | No such repository in your org — a repository in another org is reported as `404`, never `403`, so existence never leaks. |
| `409` | `name_taken` | The name is already taken in your org (create or rename). |
| `500` | `internal` | An unexpected server-side error. |
| `502` | `provision_failed` | The backing git repository could not be created; the repository could not be provisioned. |
| `503` | `org_unresolved` | The gateway could not resolve your organization; retry, and contact support if it persists. |
## API reference
For the full request and response schemas, open the Repositories groups in the [API Reference](/api-reference/introduction).
## See also
* [Run a fine-tune job](/docs/compute-fine-tune-job) - publish merged weights to a repository from a training job.
* [Deploy a model server](/docs/compute-deployment) - serve weights straight from a repository with vLLM.
# Responses
Source: https://docs.mka1.com/docs/responses
Combine inputs, retrieval, tools, and outputs in one model interaction.
Responses is the core MKA1 API for building model interactions. Send input to a model, give it access to the tools or knowledge it needs, and receive a response. The same API supports text, image, document, and audio inputs, with output capabilities determined by the selected model.
Start with [Text generation](/docs/generate-a-response) for a complete request, or follow the [Quickstart](/docs/quickstart) if you have not configured a client yet.
## Build a response
1. **Provide input.** Send text, or include [images](/docs/image-inputs), [documents](/docs/document-inputs), or [audio](/docs/audio-inputs).
2. **Add context and tools.** Retrieve context from [vector stores](/docs/vector-stores) or [graph stores](/docs/graph-retrieval). Use [function calling](/docs/function-calling), [MCP tools](/docs/mcp-tools), or [code execution](/docs/code-execution) when the model needs to act.
3. **Choose the output.** Receive text, enable [image generation](/docs/image-generation), or request [audio output](/docs/audio-responses). Check the feature guide for its model requirements and request fields.
4. **Manage the interaction.** [Stream output](/docs/streaming), continue a [conversation](/docs/conversations), or run a long request [in the background](/docs/background-responses).
## Inputs, resources, and tools
Start with [Files](/docs/files) to upload content and obtain file IDs for [document inputs](/docs/document-inputs) and [vector stores](/docs/vector-stores).
Inputs belong to a request. Resources such as [files](/docs/files), vector stores, and sandbox sessions have their own creation and management APIs and can be reused across requests.
For retrieval, upload and index your files before searching the store. The retrieval guides show how to obtain context that you can pass to a response. Graph retrieval changes how a vector store finds connected evidence.
Tools let the model request actions as part of generating a response. Function calling lets your application execute those actions; MCP connects tool servers. Shell handles broader workspace tasks, while code interpreter focuses on writing and running code. Both use the same sandbox platform; see [Code execution](/docs/code-execution).
## Choose a standalone API when appropriate
| Task | Through Responses | Standalone API |
| - | - | - |
| Generate an image | [Image generation tool](/docs/image-generation) within an interaction | [Image generation](/docs/images-api) from a direct prompt |
| Work with incoming audio | [Audio inputs](/docs/audio-inputs) for a model reply | [Speech to text](/docs/speech-to-text) for transcription |
| Run code | [Code execution tools](/docs/code-execution) chosen by the model | [Sandbox](/docs/sandbox) sessions and commands controlled by your application |
| Produce speech | [Audio output](/docs/audio-responses) from a model reply | [Text to speech](/docs/text-to-speech) from supplied text |
[Realtime voice](/docs/advanced-voice-mode) is a standalone API with its own session workflow. Start there when building a live voice interaction. For document-to-JSON extraction with reusable schemas, use the standalone [Extract API](/docs/extract-structured-data).
## Build reusable workflows
[Agents](/docs/agents-overview) build on Responses by saving instructions, model selection, and tool configuration for repeated runs. [Structured extraction](/docs/extract-structured-data) provides a dedicated workflow for turning documents and images into JSON using an inline or saved schema.
Use [prompt templates](/docs/prompt-repository) to reuse prompts, [history and memory](/docs/long-term-memory) to retain context, and [evals](/docs/evals) to measure behavior.
# Sandbox sessions
Source: https://docs.mka1.com/docs/sandbox
Create a sandbox session, run commands and code in its workspace, move files in and out, hand it to a response, and terminate it when you are done.
For model-driven execution, start with [Code execution](/docs/code-execution). The steps below cover directly creating and managing a session from your application.
Use a sandbox session when a program of yours, rather than a model, needs to run commands or code on the platform's hardware: a cleanup script an agent wrote, a test suite against a file a user uploaded, or a build step inside an automation.
A session is an isolated execution environment with a persistent `/workspace` directory.
Which provider backs it depends on the MKA1 deployment you call, and the create response reports it as `provider`: `runner-docker`, `runner-firecracker`, `runner-process`, or `in-memory`.
The [Responses API](/docs/generate-a-response) runs its `shell` and `code_interpreter` tools on these same sessions, so you do not need this API to let a model execute code.
[Build an agent with memory stores](/docs/build-an-agent-with-memory-stores) shows the `shell` tool in use, and [Sandbox sessions and the Responses API](#sandbox-sessions-and-the-responses-api) explains when to call this API yourself.
## Before you start
You need:
| Requirement | Notes |
| - | - |
| API key | Send it as `Authorization: Bearer ` on every request. |
| Sandbox scopes | `write:sandbox` creates sessions and runs anything in them; `read:sandbox` reads session records, workspace listings, downloads, and usage. Both are ordinary member scopes, so any organization member can mint a key that carries them. |
| A session id | You name sessions yourself. `session_id` is a string of 1 to 255 characters, and the API applies no other pattern. |
The [CLI command reference](/docs/cli/commands) documents no sandbox commands, so this guide shows the SDKs and curl.
## How a session works
### Kinds
| `session_kind` | What you get |
| - | - |
| `standard` (default) | A command and code sandbox with a `/workspace` directory. Everything in this guide applies to it. |
| `browser` | A session that runs headless Chrome and exposes its DevTools Protocol endpoint through the gateway. It requires a Firecracker-backed deployment; other deployments reject the request with `501 browser_sessions_not_enabled`. See [Browser sessions](#browser-sessions). |
| `coding_harness` | A managed coding-agent session that the console's Coding Harness creates and drives. Do not create these through the API. |
### Size and image
`resource_class` is optional, and `medium` is the only value the API accepts today.
`runtime_profile` picks the image: `standard` (default) or `eval-python`, the profile the [evals service](/docs/evals-python-graders) uses for Python graders.
Each session record reports the memory it reserved as `sandbox_memory_mib`.
### Lifetime and states
`ttl_seconds` (default `600`) is an idle timeout, not a total lifetime.
Every command or code run renews the session's lease, and the container is reclaimed only after `ttl_seconds` pass with no activity.
When that happens the session becomes `stopped`, but the workspace survives: files persist for 7 days across container restarts, and the record's `workspace_expires_at` says when they go.
The next command re-provisions the container and rehydrates the workspace, which takes several seconds, so raise `ttl_seconds` for interactive workloads with long pauses between commands.
Creating a session is idempotent on `session_id`.
If a session with that id already exists, the request reuses it when it is `running` or `idle`, resumes it when it is `stopped`, and purges and recreates it when it is `failed` or `terminated`.
| Status | Meaning |
| - | - |
| `queued` | Waiting for runner capacity. Only sessions created with `queue_if_full: true` enter this state; otherwise a full runner pool returns `503 sandbox_capacity_exhausted`. |
| `pending`, `provisioning` | The container is being allocated and started. Poll until it is `running` or `idle`. |
| `running`, `idle` | The container is up and accepts commands. |
| `stopped` | The idle timeout passed and the container was reclaimed. The workspace is kept until `workspace_expires_at`, and the next command brings the session back. |
| `failed` | Provisioning or the runtime failed. |
| `terminated` | You terminated it. The record stays readable. |
### The session token
Create returns a `session_token` next to the session record.
It is a credential for that one session, and it can be `null` on deployments that authorize on the API key and tenancy alone.
When it is present, pass it back on every later call: as `session_token` in the body of command, code, and terminate requests, and as the `session_token` query parameter on workspace and browser-URL requests.
Keep it on your server. Never send it to front-end code.
`X-On-Behalf-Of` works the same way. If you set it on create, send the same header on every later call for that session: sessions are scoped to the caller that created them, and this guide's later snippets omit the header only to keep them short.
## Step 1 - Create a session
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const created = await sdk.sandbox.create({
xOnBehalfOf: '', // optional — attribute the request to one of your end users
createSessionRequest: {
sessionId: 'docs-demo-session',
sessionKind: 'standard',
ttlSeconds: 600,
},
});
const sessionId = created.session.sessionId;
const sessionToken = created.sessionToken;
console.log(created.session.status, created.provider);
```
```python Python SDK theme={null}
from meetkai_mka1 import SDK
import time
sdk = SDK(bearer_auth="Bearer ")
created = sdk.sandbox.create(
session_id="docs-demo-session",
session_kind="standard",
ttl_seconds=600,
x_on_behalf_of="", # optional — attribute the request to one of your end users
)
session_id = created.session.session_id
session_token = created.session_token
print(created.session.status, created.provider)
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Components;
using System.Text;
var sdk = new SDK(bearerAuth: "Bearer ");
var created = await sdk.Sandbox.CreateAsync(
new CreateSessionRequest
{
SessionId = "docs-demo-session",
SessionKind = SessionKind.Standard,
TtlSeconds = 600,
},
xOnBehalfOf: "" // optional — attribute the request to one of your end users
);
var session = created.CreateSessionResponseValue!.Session;
var sessionId = session.SessionId;
var sessionToken = created.CreateSessionResponseValue.SessionToken;
Console.WriteLine($"{session.Status} {created.CreateSessionResponseValue.Provider}");
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/sandbox/sessions \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"session_id": "docs-demo-session",
"session_kind": "standard",
"ttl_seconds": 600
}'
```
The response carries the record, the token, and the provider that backs the session.
Trimmed to the fields this guide discusses:
```json theme={null}
{
"session": {
"session_id": "docs-demo-session",
"status": "provisioning",
"session_kind": "standard",
"resource_class": "medium",
"ttl_seconds": 600,
"workspace_expires_at": "2026-09-02T13:02:41Z",
"runtime_profile": "standard",
"sandbox_memory_mib": 256,
"created_at": "2026-08-26T13:02:41Z",
"updated_at": "2026-08-26T13:02:41Z"
},
"session_token": "",
"provider": "runner-docker"
}
```
The full record also carries the caller's `user_id`, `org_id`, `team_id`, and `api_key_id`, plus the `memory_mounts`, `sandbox_features`, and `session_key` you set.
Create request fields (the record echoes all of them except `queue_if_full`):
| Field | Notes |
| - | - |
| `session_kind` | `standard`, `browser`, or `coding_harness` (console-managed). See [Kinds](#kinds). |
| `ttl_seconds` | Idle timeout in seconds. See [Lifetime and states](#lifetime-and-states). |
| `runtime_profile` | `standard` (default) or `eval-python`. |
| `queue_if_full` | `true` queues the request when runner capacity is temporarily unavailable, returning `202` with a `queued` session, instead of failing with `503`. A browser session on a deployment without browser support still fails with `501` instead of queueing. |
| `memory_mounts` | Mounts [memory stores](/docs/build-an-agent-with-memory-stores) into the workspace, with `store_id`, `label`, and `access` of `read_only` or `read_write`. |
| `sandbox_features` | Optional feature flags. The accepted values are `python`, `git`, and `claude-code`. |
| `session_key` | An optional grouping key. `list` returns it on each record, so a caller that names sessions dynamically can still find the latest one for a key. |
`200` returns the session, which may still be `provisioning`; `202` means it is `queued`.
## Step 2 - Wait for it to be ready
Read the record until `status` is `running` or `idle`.
```ts TypeScript SDK theme={null}
const session = await sdk.sandbox.get({ sessionId });
console.log(session.status, session.workspaceExpiresAt);
```
```python Python SDK theme={null}
session = sdk.sandbox.get(session_id=session_id)
print(session.status, session.workspace_expires_at)
```
```csharp C# SDK theme={null}
var current = await sdk.Sandbox.GetAsync(sessionId);
Console.WriteLine($"{current.SessionRecord!.Status} {current.SessionRecord.WorkspaceExpiresAt}");
```
```bash CLI theme={null}
mka1 sandbox get \
--session-id docs-demo-session
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-session \
--header 'Authorization: Bearer '
```
[Lifetime and states](#lifetime-and-states) explains each status.
## Step 3 - Run a command
`command` is the program and `args` its arguments.
The command runs in `/workspace` unless you set `cwd`, with any extra `env` you pass, and is killed after `timeout_seconds` (default `60`).
```ts TypeScript SDK theme={null}
const result = await sdk.sandbox.runCommand({
sessionId,
commandRequest: {
sessionId,
sessionToken,
command: 'echo',
args: ['hello from the sandbox'],
},
});
console.log(result.exitCode, result.stdout);
```
```python Python SDK theme={null}
result = sdk.sandbox.run_command(
session_id_param=session_id,
session_id=session_id,
session_token=session_token,
command="echo",
args=["hello from the sandbox"],
)
print(result.exit_code, result.stdout)
```
```csharp C# SDK theme={null}
var command = await sdk.Sandbox.RunCommandAsync(sessionId, new CommandRequest
{
SessionId = sessionId,
SessionToken = sessionToken,
Command = "echo",
Args = new List { "hello from the sandbox" },
});
Console.WriteLine($"{command.CommandResult!.ExitCode} {command.CommandResult.Stdout}");
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-session/commands \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"session_id": "docs-demo-session",
"session_token": "",
"command": "echo",
"args": ["hello from the sandbox"]
}'
```
The result reports `stdout`, `stderr`, `exit_code`, the `files_changed` under the workspace, and `resource_usage` (`reserved_memory_mib`, `peak_memory_mib`, `memory_pressure`, `oom_killed`).
A non-zero exit code is a normal `200` response, not an HTTP error, so check `exit_code` yourself.
The Python SDK takes the path parameter as `session_id_param` and the body field as `session_id`; pass both.
## Step 4 - Run code
`run_code` takes source text and a `runtime`, so you do not have to write the code to a file first, and returns the same result shape as a command.
```ts TypeScript SDK theme={null}
const run = await sdk.sandbox.runCode({
sessionId,
codeRequest: {
sessionId,
sessionToken,
runtime: 'python',
code: 'print("2 + 2 =", 2 + 2)',
},
});
console.log(run.runtime, run.exitCode, run.stdout);
```
```python Python SDK theme={null}
run = sdk.sandbox.run_code(
session_id_param=session_id,
session_id=session_id,
session_token=session_token,
runtime="python",
code='print("2 + 2 =", 2 + 2)',
)
print(run.runtime, run.exit_code, run.stdout)
```
```csharp C# SDK theme={null}
var run = await sdk.Sandbox.RunCodeAsync(sessionId, new CodeRequest
{
SessionId = sessionId,
SessionToken = sessionToken,
Runtime = CodeRuntime.Python,
Code = "print(\"2 + 2 =\", 2 + 2)",
});
Console.WriteLine($"{run.CodeResult!.Runtime} {run.CodeResult.ExitCode} {run.CodeResult.Stdout}");
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-session/code \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"session_id": "docs-demo-session",
"session_token": "",
"runtime": "python",
"code": "print(\"2 + 2 =\", 2 + 2)"
}'
```
`runtime` accepts these values:
| Language | `runtime` values |
| - | - |
| Python | `python`, `python3` |
| JavaScript (Node) | `javascript`, `node` |
| Go | `go` |
| Shell | `bash`, `shell`, `sh` |
`runtime` defaults to `python`.
`cwd`, `env`, and `timeout_seconds` work as they do for commands.
## Step 5 - Upload and download files
Workspace paths are relative to `/workspace`: uploading to `input.csv` places the file at `/workspace/input.csv`, and a command reads it there.
Single files travel as raw bytes with `Content-Type: application/octet-stream`; archives are covered [below](#archives).
```ts TypeScript SDK theme={null}
await sdk.sandbox.uploadFile({
sessionId,
sessionToken,
filePath: 'input.csv',
requestBody: new TextEncoder().encode('id,value\n1,42\n'),
});
const download = await sdk.sandbox.downloadFile({
sessionId,
sessionToken,
filePath: 'input.csv',
});
console.log(await new Response(download).text());
```
```python Python SDK theme={null}
sdk.sandbox.upload_file(
session_id=session_id,
session_token=session_token,
file_path="input.csv",
body=b"id,value\n1,42\n",
)
download = sdk.sandbox.download_file(
session_id=session_id,
session_token=session_token,
file_path="input.csv",
)
print(download.read().decode())
```
```csharp C# SDK theme={null}
await sdk.Sandbox.UploadFileAsync(new MeetKai.MKA1.Types.Requests.UploadWorkspaceFileRequest
{
SessionId = sessionId,
SessionToken = sessionToken,
FilePath = "input.csv",
Body = Encoding.UTF8.GetBytes("id,value\n1,42\n"),
});
var download = await sdk.Sandbox.DownloadFileAsync(sessionId, "input.csv", sessionToken: sessionToken);
Console.WriteLine(Encoding.UTF8.GetString(download.Bytes!));
```
```bash Bash theme={null}
printf 'id,value\n1,42\n' > input.csv
curl "https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-session/workspace/files/input.csv?session_token=" \
--request PUT \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/octet-stream' \
--data-binary @input.csv
curl "https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-session/workspace/files/input.csv?session_token=" \
--header 'Authorization: Bearer ' \
--output input-copy.csv
```
Uploads answer with `{"status": "uploaded"}`; downloads answer with the raw bytes.
The Python SDK returns a download as a streamed `httpx.Response`, so call `read()` to get the bytes.
### Archives
For many files at once, move a zip instead of one file at a time.
| Operation | Endpoint | What it does |
| - | - | - |
| `uploadArchive` | `PUT .../workspace/archive?session_token=...` with `Content-Type: application/zip` and the zip as the body | Extracts the archive into the workspace. |
| `downloadArchive` | `POST .../workspace/archive?session_token=...` with `{"paths": ["input.csv", "out"]}` | Returns a zip of the selected workspace paths. |
## Step 6 - Inspect the workspace
The manifest lists every file in the workspace with its size and etag.
```ts TypeScript SDK theme={null}
const manifest = await sdk.sandbox.getWorkspace({ sessionId, sessionToken });
for (const file of manifest.files ?? []) {
console.log(file.path, file.size, file.etag);
}
```
```python Python SDK theme={null}
manifest = sdk.sandbox.get_workspace(session_id=session_id, session_token=session_token)
for file in manifest.files or []:
print(file.path, file.size, file.etag)
```
```csharp C# SDK theme={null}
var manifest = await sdk.Sandbox.GetWorkspaceAsync(sessionId, sessionToken: sessionToken);
foreach (var file in manifest.WorkspaceManifest!.Files ?? new List())
{
Console.WriteLine($"{file.Path} {file.Size} {file.Etag}");
}
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-session/workspace?session_token=" \
--header 'Authorization: Bearer '
```
## Step 7 - Terminate
Sessions are billed by elapsed time, so terminate one as soon as you are done with it rather than waiting for the idle timeout to reclaim the container.
```ts TypeScript SDK theme={null}
const terminated = await sdk.sandbox.terminate({
sessionId,
terminateSessionRequest: { sessionId, sessionToken },
});
console.log(terminated.session.status);
```
```python Python SDK theme={null}
terminated = sdk.sandbox.terminate(
session_id_param=session_id,
session_id=session_id,
session_token=session_token,
)
print(terminated.session.status)
```
```csharp C# SDK theme={null}
var terminated = await sdk.Sandbox.TerminateAsync(sessionId, new TerminateSessionRequest
{
SessionId = sessionId,
SessionToken = sessionToken,
});
Console.WriteLine(terminated.TerminateSessionResponseValue!.Session.Status);
```
```bash CLI theme={null}
mka1 sandbox terminate \
--body '{
"session_id": "docs-demo-session",
"session_token": ""
}' \
--session-id docs-demo-session
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-session/terminate \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"session_id": "docs-demo-session",
"session_token": ""
}'
```
Termination releases the backing resources and returns the record with `status` set to `terminated`.
Pass `expected_session_kind` if you want the call to refuse a session of a different kind than the one you meant to stop.
## Browser sessions
Create with `session_kind: "browser"` and the session runs headless Chrome instead of a command sandbox.
Three operations are specific to it:
| Operation | What it returns | When to use it |
| - | - | - |
| `getBrowserUrl` (`GET .../browser-url`) | The public gateway URL of the session's Chrome DevTools Protocol endpoint on port `9222`, with `session_token` already in the query string. | Point Playwright, or any CDP client that accepts an HTTP endpoint, at this URL. Send your MKA1 API-key `Authorization` header on the HTTP and WebSocket requests alike. |
| `proxyBrowserPortRequest` (`GET .../ports/{port}/{subpath}`) | The proxied response from an exposed port, for example `json/version` or `json/list` on port `9222`. | Fetch a single CDP document through the SDK without building the URL yourself. Clients that need a WebSocket endpoint read `json/version` and use its rewritten `webSocketDebuggerUrl`. |
| `getUrl` (`GET .../url`) | The same as `getBrowserUrl`, with an optional `port` query parameter. | Deprecated alias kept for older clients; use `getBrowserUrl`. |
Insert subpaths before the query string, as in `/ports/9222/json/version?session_token=...`.
Standard sessions expose no public URL: `browser-url` answers `501` for them, so use the command, code, and workspace operations instead.
```ts TypeScript SDK theme={null}
const browser = await sdk.sandbox.create({
createSessionRequest: { sessionId: 'docs-demo-browser', sessionKind: 'browser' },
});
const endpoint = await sdk.sandbox.getBrowserUrl({
sessionId: browser.session.sessionId,
sessionToken: browser.sessionToken,
});
console.log(endpoint.url);
const version = await sdk.sandbox.proxyBrowserPortRequest({
sessionId: browser.session.sessionId,
sessionToken: browser.sessionToken,
port: 9222,
subpath: 'json/version',
});
console.log(version);
```
```python Python SDK theme={null}
browser = sdk.sandbox.create(session_id="docs-demo-browser", session_kind="browser")
endpoint = sdk.sandbox.get_browser_url(
session_id=browser.session.session_id,
session_token=browser.session_token,
)
print(endpoint.url)
version = sdk.sandbox.proxy_browser_port_request(
session_id=browser.session.session_id,
session_token=browser.session_token,
port=9222,
subpath="json/version",
)
print(version)
```
```csharp C# SDK theme={null}
var browser = await sdk.Sandbox.CreateAsync(new CreateSessionRequest
{
SessionId = "docs-demo-browser",
SessionKind = SessionKind.Browser,
});
var browserSession = browser.CreateSessionResponseValue!;
var endpoint = await sdk.Sandbox.GetBrowserUrlAsync(
browserSession.Session.SessionId,
sessionToken: browserSession.SessionToken
);
Console.WriteLine(endpoint.SessionUrlResponse!.Url);
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-browser/browser-url?session_token=" \
--header 'Authorization: Bearer '
curl "https://apigw.mka1.com/api/v1/sandbox/sessions/docs-demo-browser/ports/9222/json/version?session_token=" \
--header 'Authorization: Bearer '
```
Wait for the session to reach `running` as in Step 2 before asking for the URL, and terminate it as in Step 7 when you are done.
The C# tab stops at the URL; the proxy call takes the same session id, port, and token.
## Sandbox sessions and the Responses API
See [Code execution](/docs/code-execution) for complete Responses examples with automatic sandboxes, file inputs, and existing sessions.
When a response uses the `shell` or `code_interpreter` tool, the gateway creates a sandbox session on your behalf, runs the model's commands in it, and returns the output to the model.
It creates that session with `queue_if_full: true` and its own default idle timeout.
The gateway names these sessions so that the same caller reuses the same sandbox across responses.
The `shell` tool reuses the `container_reference.container_id` from its tool definition when there is one, and `code_interpreter` reuses its `container` string; without either, the gateway derives a key from the API key's user and the end user.
To find them, list sessions and match on `session_key`.
The tools create these sessions as the end user in `X-On-Behalf-Of` when that header is present, and as the API key's user otherwise, so a later request reuses them only when it carries the same header.
A key that drives either tool needs both `read:sandbox` and `write:sandbox`: the flow polls session state and downloads files as well as running commands.
Let a response create the session when the model should decide what to run.
Call the sandbox API yourself when:
* Your own code decides what runs, such as a fixed pipeline or a CI-style job.
* You need to move files in and out without spending a model turn on it.
* You want to control the session's id, `ttl_seconds`, or `runtime_profile`.
* You need a browser session.
The two can share a session.
Create it here, upload its inputs, then hand the id to a response's `shell` tool as `environment: { type: "container_reference", container_id: "" }`; the response runs its commands in your workspace, and you download the results afterwards.
The session must belong to the same caller: send the same `X-On-Behalf-Of` header you created it with, since sessions are scoped to the organization, team, and user that created them.
## Usage
`GET /api/v1/sandbox/usage` aggregates sandbox activity over a time range: session starts, stops, and terminations, command and code runs, and workspace transfers.
Buckets are calendar-aligned in UTC. `start_time` is snapped down and `end_time` snapped up to the nearest `bucket_width` boundary (`1m`, `1h`, or `1d`), so the first and last buckets can extend slightly past the range you asked for.
Callers see their own usage, organization admins see their team's, and cluster admins can pass `all_orgs` or `org_ids`.
```ts TypeScript SDK theme={null}
const usage = await sdk.usage.sandbox({
startTime: Math.floor(Date.now() / 1000) - 7 * 24 * 3600,
bucketWidth: '1d',
groupBy: ['operation'],
});
for (const bucket of usage.data ?? []) {
for (const row of bucket.results ?? []) {
console.log(bucket.startTime, row.operation, row.numOperations, row.durationMs);
}
}
```
```python Python SDK theme={null}
usage = sdk.usage.sandbox(
start_time=int(time.time()) - 7 * 24 * 3600,
bucket_width="1d",
group_by=["operation"],
)
for bucket in usage.data or []:
for row in bucket.results or []:
print(bucket.start_time, row.operation, row.num_operations, row.duration_ms)
```
```csharp C# SDK theme={null}
var usage = await sdk.Usage.SandboxAsync(new MeetKai.MKA1.Types.Requests.GetSandboxUsageRequest
{
StartTime = DateTimeOffset.UtcNow.AddDays(-7).ToUnixTimeSeconds(),
BucketWidth = SandboxUsageBucketWidth.Oned,
GroupBy = new List { "operation" },
});
foreach (var bucket in usage.SandboxUsagePage!.Data ?? new List())
{
foreach (var row in bucket.Results ?? new List())
{
Console.WriteLine($"{bucket.StartTime} {row.Operation} {row.NumOperations} {row.DurationMs}");
}
}
```
```bash Bash theme={null}
curl "https://apigw.mka1.com/api/v1/sandbox/usage?start_time=&bucket_width=1d&group_by=operation" \
--header 'Authorization: Bearer '
```
Each result row carries `num_operations`, `num_sessions`, `request_count`, `duration_ms`, `workspace_bytes_in`, `workspace_bytes_out`, `files_changed_count`, `oom_killed_count`, `peak_memory_mib`, and `reserved_memory_mib`, plus whichever grouping fields you asked for (`operation`, `session_kind`, `provider`, `user_id`, `api_key_id`, `org_id`).
The `operation` values are `session_start`, `session_stop`, `session_terminate`, `turn`, `repo_task`, `command`, `code`, `workspace_manifest`, `workspace_download`, `workspace_archive_download`, `workspace_upload`, and `workspace_archive_upload`.
Usage counts activity; it does not price it.
Spend in currency comes from the budgeting API's cost endpoint (`sdk.usage.costs`, `GET /api/v1/budgeting/usage/costs`), which is admin-only.
## For cluster admins
**Cluster-admin bearer required.**
`getPricing` and `setPricing` answer `403` to any other caller.
Spend for your own organization comes from `sdk.usage.costs` instead.
The budgeting service bills sandbox time as `hours × (per_hour + reserved_memory_GiB × per_gib_hour)` against a rate card keyed by SKU: `standard`, `browser`, and `eval-python`.
A SKU with no configured rate accrues no spend.
Shown for the TypeScript SDK and curl; the other SDKs expose the same two operations.
```ts TypeScript SDK theme={null}
// Cluster admins only.
const pricing = await sdk.sandbox.getPricing();
console.log(pricing.rates, pricing.updatedAt);
```
```bash CLI theme={null}
mka1 sandbox get-pricing
```
```bash Bash theme={null}
# Cluster admins only.
curl https://apigw.mka1.com/api/v1/sandbox/pricing \
--header 'Authorization: Bearer '
```
`setPricing` (`PUT /api/v1/sandbox/pricing`, cluster admins only) replaces the whole card: SKUs you omit become unpriced.
The new rates apply from the next meter window without a restart.
## Troubleshooting
| Symptom | Cause | Fix |
| - | - | - |
| `403` with `detail.required_scope` in the body | The key lacks `read:sandbox` or `write:sandbox`. | Mint a key that carries both. |
| `503 sandbox_capacity_exhausted` on create | Runner capacity is exhausted. | Retry later, or create with `queue_if_full: true` and poll the `queued` session. |
| `409` on create | A session with that id already exists and was not reused in place. | Read it with `get`. If it is `running`, `idle`, or `stopped`, use it as is; if it is still provisioning, poll until it settles. |
| `410` with `session inactive` | The session is `failed` or `terminated`. | Create again with the same `session_id` to purge and recreate it. |
| `501 browser_sessions_not_enabled` on create | The deployment is not Firecracker-backed, so it cannot run browser sessions. | Use a `standard` session, or a deployment that supports browser sessions. |
| `501` from `GET .../browser-url` | The session is a `standard` one; only browser sessions expose a public URL. | Use the command, code, and workspace operations. |
| A command returns `exit_code` other than `0` | The program failed, not the API; the call itself returns `200`. | Read `stderr`. |
| A command stops at exactly `timeout_seconds` | The request's timeout ran out; the default is `60`. | Raise `timeout_seconds` on that request. |
| The first command after a pause is slow | The idle timeout reclaimed the container and the workspace was rehydrated. | Raise `ttl_seconds` on sessions with long gaps between commands. |
| A session you created is not found by a later call | The create carried `X-On-Behalf-Of` and this call does not, or the reverse. Sessions are scoped to the caller that created them. | Send the same header on every call for that session. |
## API reference
For the full request and response schemas, open the Sandbox API groups (Sessions, Execution, Workspace, Sandbox Usage, Sandbox Pricing) and the Browser group in the [API Reference](/api-reference/introduction).
## See also
* [Build an agent with memory stores](/docs/build-an-agent-with-memory-stores) - the `shell` tool with memory stores mounted into the sandbox.
* [Python graders](/docs/evals-python-graders) - grading code the evals service runs in a sandbox.
* [Usage auditing](/docs/usage-auditing) - the sandbox command dashboards and log views in SigNoz.
# SDKs
Source: https://docs.mka1.com/docs/sdks
Install a supported client and connect it to your MKA1 deployment.
## Choose a client
MKA1 ships SDKs for TypeScript, Python, and C#, plus a standalone `mka1` CLI. Every client authenticates with your API key as a Bearer token and targets the API gateway. The default hosted gateway is `https://apigw.mka1.com`.
**Private clusters**
On a private deployment, replace `https://apigw.mka1.com` with your cluster's own gateway host everywhere below. Pass it as the SDK's `serverURL` / `server_url` / `serverUrl` option, or set it once for the CLI. Your administrator can tell you the gateway URL (it's the API counterpart to your console address).
### TypeScript - @meetkai/mka1
The TypeScript SDK installs from the npm package registry:
```bash theme={null}
npm add @meetkai/mka1
```
```ts theme={null}
import { SDK } from '@meetkai/mka1';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
```
### Python - [meetkai-mka1](https://pypi.org/project/meetkai-mka1/)
Requires Python 3.10 or newer:
```bash theme={null}
pip install meetkai-mka1
```
```python theme={null}
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
```
### C# - [MeetKai.MKA1](https://www.nuget.org/packages/MeetKai.MKA1/)
```bash theme={null}
dotnet add package MeetKai.MKA1
```
```csharp theme={null}
using MeetKai.MKA1;
var sdk = new SDK(bearerAuth: "Bearer ");
```
### CLI - [mka1](https://docs.mka1.com/docs/cli/introduction)
Pre-built binaries are served from downloads.mka1.com. On macOS (Apple silicon):
```bash theme={null}
curl -fsSL https://downloads.mka1.com/darwin/mka1_darwin_arm64-latest.tar.gz \
| tar -xz -C /usr/local/bin mka1
mka1 version
```
Swap arm64 for x86\_64 on Intel; .deb/.rpm packages and a Windows .zip are linked from the [CLI guide](https://docs.mka1.com/docs/cli/introduction). Then set your key and run any command:
```bash theme={null}
export MKA1_BEARER_AUTH="Bearer "
mka1 llm models list
```
For a persistent setup that stores secrets in your OS keychain, see [authenticate the CLI](https://docs.mka1.com/docs/cli/authentication).
## Next steps
* [Quickstart](/docs/quickstart)
* [OpenAI compatibility](/docs/openai-compatibility)
* [CLI installation](/docs/cli/introduction)
# Service accounts
Source: https://docs.mka1.com/docs/service-accounts
Use non-human identities for production applications and automation.
## Create a service account
For production systems, CI runners, backend services, and scheduled jobs, use a **service account** instead of a person's credentials. A service account is a non-human machine identity you attach to one or more teams, and mint API keys for. You can create one by navigating to **Access → Service accounts** and clicking **New service account** in the top right corner. Because keys inherit the team scope, detaching a service account from a team (or deleting it) immediately stops every key minted for it on that team, giving you a clean kill switch for production credentials.
## Create its API key
Follow [API keys](/docs/authentication) and select the service account as the principal. Choose the team and permissions needed by the application.
## Access lifecycle
Review team membership and key permissions when an application changes ownership. Before replacing a credential, identify the workloads using it and update those workloads before retiring the old key.
# Short-lived tokens
Source: https://docs.mka1.com/docs/short-lived-tokens
Exchange an API key for a scoped, time-limited token.
## Exchange an API key for a JWT
Use `POST /api/v1/authentication/api-keys/exchange-token` when you need a short-lived JWT for a downstream service.
Send your MKA1 API key in `Authorization`.
Then pass a JSON body with:
* `audience`: The service URL that should accept the token.
* `externalUserId`: Your end user ID for the JWT subject.
* `expiresIn`: Optional token lifetime in seconds. The OpenAPI spec allows 300 to 2592000.
* `permissions`: Optional subset of the key's scopes (its permissions, for example `read:responses` or `read:files`) to embed in the token. If omitted, the token carries every scope the key has. A token can narrow the key's scopes but never widen them.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const result = await sdk.auth.apiKeys.exchangeToken({
requestBody: {
audience: 'https://my-awesome-website.com',
externalUserId: 'user_123',
expiresIn: 3600,
// permissions: ['read:responses', 'read:files'],
},
})
```
```python Python SDK theme={null}
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
jwt = sdk.auth.api_keys.exchange_token(
audience="https://my-awesome-website.com",
external_user_id="user_123",
expires_in=3600,
# permissions=["read:responses", "read:files"],
)
# Use the JWT for subsequent requests
authed = SDK(bearer_auth=f"Bearer {jwt.token}")
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Requests;
using MeetKai.MKA1.Types.Components;
var sdk = new SDK(bearerAuth: "Bearer ");
var result = await sdk.Auth.ApiKeys.ExchangeTokenAsync(
body: new ExchangeApiKeyTokenRequestBody()
{
Audience = "https://my-awesome-website.com",
ExternalUserId = "user_123",
ExpiresIn = 3600,
// Permissions = new List() { "read:responses", "read:files" },
});
Console.WriteLine(result.Object!.Token);
```
```bash CLI theme={null}
mka1 auth api-keys exchange-token \
--audience https://my-awesome-website.com \
--external-user-id user_123 \
--expires-in 3600
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/authentication/api-keys/exchange-token \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"audience": "https://my-awesome-website.com",
"externalUserId": "user_123",
"expiresIn": 3600
}'
```
A successful response returns a JSON object with `token`.
## Use a JWT for subsequent requests
Once you have a JWT from the exchange endpoint, use it as a bearer token in place of your API key.
This lets you issue short-lived credentials to downstream services or end users without exposing your API key.
```ts TypeScript SDK theme={null}
// Use the JWT returned from the exchange endpoint
const jwtSdk = new SDK({ bearerAuth: `Bearer ${result.token}` })
const response = await jwtSdk.llm.responses.create({
responsesCreateRequest: {
model: 'auto',
input: 'Write a short welcome message.',
},
})
```
```python Python SDK theme={null}
# Use the JWT returned from the exchange endpoint
authed = SDK(bearer_auth=f"Bearer {jwt.token}")
res = authed.llm.responses.create(
model="auto",
input="Write a short welcome message.",
)
```
```csharp C# SDK theme={null}
// Use the JWT returned from the exchange endpoint
var jwtSdk = new SDK(bearerAuth: $"Bearer {result.Object!.Token}",
serverUrl: "https://apigw.mka1.com");
var res = await jwtSdk.Llm.Responses.CreateAsync(new ResponsesCreateRequest()
{
Model = "auto",
Input = ResponsesCreateRequestInput.CreateStr("Write a short welcome message."),
});
```
```bash CLI theme={null}
# Pass the JWT explicitly via -H to override MKA1_BEARER_AUTH
mka1 llm responses create \
--model auto \
--input '"Write a short welcome message."' \
-H 'Authorization: Bearer '
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer " \
--data '{
"model": "auto",
"input": "Write a short welcome message."
}'
```
## Related guides
See [End-user identity](/docs/end-user-identity) for delegated requests and [Tenant isolation](/docs/authentication-deep-dive) for the validation path.
# Signed artifacts and supply chain
Source: https://docs.mka1.com/docs/signed-artifacts
How MKA1 ensures container image integrity through immutable artifact tagging, controlled CI/CD pipelines, and private registry enforcement.
MKA1 enforces a deterministic supply chain where every container image is traceable to a specific source commit, built exclusively through automated CI pipelines, and stored in private registries that reject external artifacts.
## What is active
### Immutable artifact tagging
Every container image built by the platform is tagged with the originating git commit SHA. This creates an immutable, one-to-one link between source code and the deployed binary:
* Images are pushed to Amazon ECR with commit-SHA tags (e.g., `sha-a1b2c3d`), ensuring each artifact is uniquely identifiable.
* ECR repositories are configured as private registries scoped to the organization's AWS account.
* ECR lifecycle policies enforce a 30-day retention window for commit-SHA images, keeping only the `latest` tag indefinitely.
### Controlled CI/CD pipeline
All container images originate from GitHub Actions workflows -- no manual image pushes are permitted:
* Deployment workflows authenticate with AWS via OIDC federation (no long-lived credentials).
* GitHub Actions use pinned action versions for reproducible, deterministic builds.
* Docker Buildx produces multi-platform images from a consistent build environment.
* Dependency integrity is verified during builds (e.g., `go mod verify` for Go modules).
* Private module access is controlled via scoped GitHub PATs rather than broad credentials.
### Private registry enforcement
Kubernetes deployments pull images exclusively from our private Amazon ECR registries:
* All service manifests reference fully-qualified ECR image URIs within the organization's AWS account.
* No public or third-party registries are referenced in production workloads.
* ECR native vulnerability scanning is enabled, providing automated assessment of image contents.
### Secrets and key management
* All secrets are encrypted at rest using SOPS with a customer-managed AWS KMS key.
* Secrets are never stored in plaintext in the repository or in CI logs.
* Kubernetes cluster access is governed by IAM-integrated RBAC, restricting who can interact with workloads and registries.
## How we validate it
We validate the supply chain through infrastructure-as-code review and live cluster inspection.
**Source-to-image traceability:** Every deployed image tag maps to a git commit SHA. Given any running container, we can identify the exact source revision:
```bash theme={null}
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
```
**Registry origin verification:** We confirm that all running workloads pull exclusively from our private ECR:
```bash theme={null}
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | sort -u
```
**CI pipeline audit:** GitHub Actions workflow runs are logged and auditable, providing a full history of who triggered each build and which commit produced each image.
## Evidence
### ECR image with commit-SHA tag
```text theme={null}
REPOSITORY TAG DIGEST
[redacted-account].dkr.ecr.us-west-2... sha-a1b2c3d sha256:[redacted]
[redacted-account].dkr.ecr.us-west-2... latest sha256:[redacted]
```
### Kubernetes pods pulling from private ECR
```text theme={null}
mkllm-gateway-... [redacted-account].dkr.ecr.us-west-2.amazonaws.com/mkllm-gateway:sha-[redacted]
mkllm-worker-... [redacted-account].dkr.ecr.us-west-2.amazonaws.com/mkllm-worker:sha-[redacted]
mk1-api-... [redacted-account].dkr.ecr.us-west-2.amazonaws.com/mk1-api:sha-[redacted]
kong-... [redacted-account].dkr.ecr.us-west-2.amazonaws.com/kong:sha-[redacted]
```
### GitHub Actions workflow enforcing CI-only builds
```yaml theme={null}
# Excerpt from deploy-mk1.yaml
on:
push:
branches: [main]
paths: ["mk1/**"]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: aws-actions/configure-aws-credentials@v4
- uses: aws-actions/amazon-ecr-login@v2
- run: skaffold run -p ${{ matrix.environment }}
```
# Subagents
Source: https://docs.mka1.com/docs/spawn-subagents-using-the-responses-api
Use a function tool on the MKA1 API Responses resource to let one response spawn child responses and continue after they all return.
Use this pattern when you want one response to break work into smaller tasks.
This pattern implements a synchronous child-response delegation loop.
A parent response calls a function tool that your app resolves by running another Responses request.
One child result or many child results are returned to the parent as `function_call_output`, and the parent continues generation.
A child response is sometimes called a subagent.
In this guide, it is just another Responses request that performs a focused task.
Parent response
-> `function_call` `spawn_subagent`
-> your app runs one or more child responses
-> child results returned as `function_call_output`
-> parent response resumes generation
## How the loop works
In this pattern the parent response pauses whenever it calls `spawn_subagent`.
Your app executes the delegated tasks and then resumes the parent with the results.
1. Create a parent response with a `spawn_subagent` function tool.
2. When the model calls the tool, parse each tool call's arguments.
3. Run one or more child Responses requests to perform the delegated tasks.
4. Wait for all child responses to finish.
5. Return each child result as `function_call_output` using the matching `call_id`.
6. Resume the parent response with `previous_response_id`.
7. Repeat until the parent produces a normal assistant `message`.
## Define a tool for delegation
Keep the tool focused.
Pass only the fields the child response needs.
```json theme={null}
{
"type": "function",
"name": "spawn_subagent",
"description": "Delegate a focused task to a child response and return the result.",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"task": {
"type": "string",
"description": "The task for the child response."
},
"instructions": {
"type": "string",
"description": "Optional instructions for the child response."
},
"model": {
"type": "string",
"description": "Optional model override for the child response."
}
},
"required": ["task"],
"additionalProperties": false
}
}
```
Use `tool_choice: "auto"` when the model should decide when to delegate.
Use `tool_choice: "required"` when every turn must go through a tool.
## TypeScript SDK recipe
This example uses `sdk.llm.responses.create` for both the parent and child responses.
It allows the parent to emit multiple `spawn_subagent` calls in one turn.
Your app runs those child responses concurrently, waits for all of them to finish, and then resumes the parent once with every tool result.
Keep each child result small so the parent can use it in the next turn without consuming too much context.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
import type { ResponseObject } from "@meetkai/mka1/models/components";
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const spawnSubagentTool = {
type: "function" as const,
name: "spawn_subagent",
description: "Delegate a focused task to a child response and return the result.",
strict: true,
parameters: {
type: "object",
properties: {
task: { type: "string" },
instructions: { type: "string" },
model: { type: "string" },
},
required: ["task"],
additionalProperties: false,
},
};
type SpawnSubagentArgs = {
task: string;
instructions?: string;
model?: string;
};
async function runChildResponse(args: SpawnSubagentArgs) {
const child = await sdk.llm.responses.create({
responsesCreateRequest: {
model: args.model ?? "auto",
instructions:
args.instructions ??
"You are a specialist assistant. Complete the task and return the result only.",
input: args.task,
store: true,
},
}) as ResponseObject;
return {
response_id: child.id,
output_text: child.outputText,
};
}
export async function runDelegatingAgent(input: string) {
let response = await sdk.llm.responses.create({
responsesCreateRequest: {
model: "auto",
instructions:
"You are an orchestrator. Use spawn_subagent for focused side tasks. You may call it multiple times in one turn when tasks can be parallelized. After all tool results return, answer the user directly.",
input,
tools: [spawnSubagentTool],
toolChoice: "auto",
parallelToolCalls: true,
maxToolCalls: 8,
store: true,
},
}) as ResponseObject;
while (true) {
const toolCalls = response.output.filter(
(item): item is {
type: "function_call";
name: string;
callId: string;
arguments: string;
} => item.type === "function_call" && item.name === "spawn_subagent",
);
if (toolCalls.length === 0) {
return response.outputText;
}
const toolOutputs = await Promise.all(
toolCalls.map(async (toolCall) => {
const args = JSON.parse(toolCall.arguments) as SpawnSubagentArgs;
const childResult = await runChildResponse(args);
return {
type: "function_call_output" as const,
callId: toolCall.callId,
output: JSON.stringify(childResult),
};
}),
);
response = await sdk.llm.responses.create({
responsesCreateRequest: {
model: response.model,
previousResponseId: response.id,
input: toolOutputs,
tools: [spawnSubagentTool],
parallelToolCalls: true,
maxToolCalls: 8,
store: true,
},
}) as ResponseObject;
}
}
```
## Fan out and wait for all child responses
When `parallel_tool_calls` is `true`, the parent can emit several `function_call` items in one turn.
Treat that set of tool calls as a batch.
Start every child response, wait for all of them to finish, and only then resume the parent.
This creates a barrier:
1. Parent response emits many `function_call` items.
2. Your app starts many child responses.
3. Your app waits for all child responses to complete.
4. Your app sends all `function_call_output` items back in one follow-up request.
5. Parent response continues with the full set of delegated results.
If you resume the parent early with only part of the batch, the model continues without the missing results.
That usually makes the orchestration less predictable.
The key fan-in step looks like this:
```ts theme={null}
const toolOutputs = await Promise.all(
toolCalls.map(async (toolCall) => {
const args = JSON.parse(toolCall.arguments) as SpawnSubagentArgs;
const childResult = await runChildResponse(args);
return {
type: "function_call_output" as const,
callId: toolCall.callId,
output: JSON.stringify(childResult),
};
}),
);
```
If your app acts for an end user, send the same `X-On-Behalf-Of` value on the parent and child requests.
If a child response may take longer, you can set `background: true` on the child request and poll with `sdk.llm.responses.get({ responseId })` until it completes.
When you fan out to multiple child responses, wait until every child result is available before you resume the parent response.
## Raw Responses request for the resume step
The critical handoff is the follow-up request.
You pass every tool result back in `input` and point to the earlier parent turn with `previous_response_id`.
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"model": "auto",
"previous_response_id": "resp_parent123",
"input": [
{
"type": "function_call_output",
"call_id": "call_abc123",
"output": "{\"response_id\":\"resp_child456\",\"output_text\":\"Research complete. Recommend a staged rollout.\"}"
},
{
"type": "function_call_output",
"call_id": "call_def456",
"output": "{\"response_id\":\"resp_child789\",\"output_text\":\"Draft complete. Headline: Faster rollout with lower risk.\"}"
}
]
}'
```
If you are not acting for an end user, omit `X-On-Behalf-Of`.
## Basic error handling and recovery
In real systems, this loop will fail sometimes.
Common failures include malformed tool arguments, child request timeouts, upstream 5xx errors, rate limits, and child outputs that are too weak to be useful.
The safest pattern is:
* Parse tool arguments defensively.
* Retry transient child request failures a small number of times with backoff.
* Return a structured failure payload to the parent instead of crashing the whole batch when one child fails.
* Keep child results small and explicit so the parent can decide whether to continue, retry, or answer with partial results.
One simple approach is to wrap child execution and always return either a success object or an error object:
```ts TypeScript SDK theme={null}
type ChildSuccess = {
ok: true;
response_id: string;
output_text: string;
};
type ChildFailure = {
ok: false;
error_code: "invalid_arguments" | "child_request_failed";
message: string;
};
type ChildResult = ChildSuccess | ChildFailure;
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function runChildResponseWithRecovery(rawArgs: string): Promise {
let args: SpawnSubagentArgs;
try {
args = JSON.parse(rawArgs) as SpawnSubagentArgs;
if (!args.task || typeof args.task !== "string") {
return {
ok: false,
error_code: "invalid_arguments",
message: "spawn_subagent requires a string task",
};
}
} catch {
return {
ok: false,
error_code: "invalid_arguments",
message: "Could not parse spawn_subagent arguments as JSON",
};
}
for (let attempt = 0; attempt < 3; attempt += 1) {
try {
const child = await sdk.llm.responses.create({
responsesCreateRequest: {
model: args.model ?? "auto",
instructions:
args.instructions ??
"You are a specialist assistant. Complete the task and return the result only.",
input: args.task,
store: true,
},
}) as ResponseObject;
return {
ok: true,
response_id: child.id,
output_text: child.outputText ?? "",
};
} catch (error) {
const isLastAttempt = attempt === 2;
if (isLastAttempt) {
return {
ok: false,
error_code: "child_request_failed",
message:
error instanceof Error ? error.message : "Child response failed",
};
}
await sleep(500 * (attempt + 1));
}
}
return {
ok: false,
error_code: "child_request_failed",
message: "Child response failed",
};
}
```
Then fan the results back into the parent even if some children fail:
```ts theme={null}
const toolOutputs = await Promise.all(
toolCalls.map(async (toolCall) => {
const childResult = await runChildResponseWithRecovery(toolCall.arguments);
return {
type: "function_call_output" as const,
callId: toolCall.callId,
output: JSON.stringify(childResult),
};
}),
);
```
This lets the parent see partial failures and continue reasoning.
For example, the parent can decide to retry with a narrower task, launch a replacement subagent, or answer with the available successful child results while noting the gap.
For long-running children, you can also combine this with `background: true` plus polling.
The recovery logic stays the same: wait for the child to reach a terminal state, then return either a success payload or a structured failure payload to the parent.
## Practical limits
* Keep `parallel_tool_calls` set to `true` when the parent should be able to delegate several child responses in one turn.
* Set `parallel_tool_calls` to `false` only when child responses share state or must run in order.
* Set `max_tool_calls` so a parent response cannot loop forever.
* Keep child outputs compact so the parent can incorporate the result without consuming too much context.
* Keep `store: true` while you build the workflow so you can inspect parent and child responses later.
* Use the Responses input items page in the [API Reference](/api-reference/introduction) when you need to debug the exact items sent back to the model.
## See also
Review [making deep research with subagents](/docs/making-deep-research-with-subagents) for a concrete research-oriented implementation of this pattern.
Review [generate a response](/docs/generate-a-response) for the base Responses request pattern.
Use [manage conversations](/docs/conversations) when you want the parent or child workflow to keep durable state outside a single response chain.
# Speech to text
Source: https://docs.mka1.com/docs/speech-to-text
Transcribe recordings and identify speakers.
This standalone API transcribes supplied audio. To ask a model to respond to audio instead, see [Audio inputs](/docs/audio-inputs).
## Transcribe audio
Send an audio file to the transcription endpoint when you want text output from a recorded file.
If your app acts on behalf of an end user, also send `X-On-Behalf-Of`.
Supported audio formats: `FLAC`, `MP3`, `MP4`, `MPEG`, `MPGA`, `M4A`, `OGG`, `WAV`, `WebM`.
To save the transcription (and input audio) to history, set `store=true`.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
import { openAsBlob } from 'node:fs';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const result = await sdk.llm.speech.transcribe({
xOnBehalfOf: '', // optional — attribute the request to one of your end users
language: 'en',
prompt: 'This is a technical podcast about machine learning.',
temperature: 0.2,
store: true,
requestBody: {
file: await openAsBlob('episode.wav'),
},
});
console.log(result.text);
console.log(result.language);
console.log(result.confidence);
```
```python Python SDK theme={null}
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
result = sdk.llm.speech.transcribe(
file={"file_name": "episode.wav", "content": open("episode.wav", "rb")},
language="en",
prompt="This is a technical podcast about machine learning.",
temperature=0.2,
store=True,
)
print(result.text)
print(result.language)
print(result.confidence)
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Components;
using MeetKai.MKA1.Types.Requests;
var sdk = new SDK(bearerAuth: "Bearer ");
var result = await sdk.Llm.Speech.TranscribeAsync(new TranscribeRequest()
{
Language = "en",
Prompt = "This is a technical podcast about machine learning.",
Temperature = 0.2,
Store = true,
Body = new TranscribeRequestBody()
{
File = new TranscribeFile()
{
FileName = "episode.wav",
Content = System.IO.File.ReadAllBytes("episode.wav"),
},
},
});
Console.WriteLine(result.TranscriptionResponse!.Text);
Console.WriteLine(result.TranscriptionResponse!.Language);
Console.WriteLine(result.TranscriptionResponse!.Confidence);
```
```bash CLI theme={null}
mka1 llm speech transcribe \
--file ./episode.wav \
--language en \
--prompt 'This is a technical podcast about machine learning.' \
--temperature 0.2 \
--store \
-H 'X-On-Behalf-Of: '
```
```bash Bash theme={null}
curl 'https://apigw.mka1.com/api/v1/llm/speech/transcriptions?language=en&prompt=This%20is%20a%20technical%20podcast%20about%20machine%20learning.&temperature=0.2&store=true' \
--request POST \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--form 'file=@episode.wav'
```
The response includes the transcript text plus detected language and confidence:
```json theme={null}
{
"text": "Hello! We're excited to show you our native speech capabilities.",
"language": "en",
"confidence": 0.8429018476208717
}
```
## Separate speakers in one transcript
If you need diarization, enable speaker data in the transcription request.
When enabled, the response can include a `speakers` array with speaker-labeled segments and timing metadata.
For `include_speaker_data`, upload WAV or PCM audio for non-streaming transcription. Other audio formats return `400 BAD_REQUEST` with the message `Speaker diarization currently requires WAV/PCM audio for non-streaming transcription`.
```ts TypeScript SDK theme={null}
const result = await sdk.llm.speech.transcribe({
xOnBehalfOf: '',
language: 'en',
includeSpeakerData: true,
prompt: 'This is a short podcast clip about AI product updates.',
temperature: 0.2,
requestBody: {
file: await openAsBlob('panel.wav'),
},
});
console.log(result.speakers);
```
Example response with speaker separation:
```json theme={null}
{
"text": "Welcome back to the show. Today we're looking at how speech APIs fit into production apps. We'll keep it practical and focus on latency, accuracy, and speaker turns.",
"language": "en",
"confidence": 0.91177404,
"speakers": [
{
"speaker": "Speaker-1",
"text": "Welcome back to the show.",
"confidence": 0.91177404,
"offset_ms": 80,
"duration_ms": 1280
},
{
"speaker": "Speaker-2",
"text": "Today we're looking at how speech APIs fit into production apps.",
"confidence": 0.91177404,
"offset_ms": 1540,
"duration_ms": 3380
},
{
"speaker": "Speaker-1",
"text": "We'll keep it practical and focus on latency, accuracy, and speaker turns.",
"confidence": 0.91177404,
"offset_ms": 5220,
"duration_ms": 3660
}
]
}
```
Use the top-level `text` field when you need a single merged transcript.
Use `speakers` when you need captions, turn-taking, or downstream speaker analytics.
# Streaming
Source: https://docs.mka1.com/docs/streaming
Receive generated text incrementally from the Responses API.
## Stream text as it is generated
Set `stream` to `true` to receive server-sent events instead of waiting for the full response.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
import { CreateAcceptEnum } from '@meetkai/mka1/sdk/responses';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const result = await sdk.llm.responses.create({
responsesCreateRequest: {
model: 'auto',
input: 'Write three release notes bullets for our docs update.',
stream: true,
},
}, { acceptHeaderOverride: CreateAcceptEnum.textEventStream });
```
```ts OpenAI SDK theme={null}
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: '',
baseURL: 'https://apigw.mka1.com/api/v1/llm/',
defaultHeaders: { 'X-On-Behalf-Of': '' },
});
const stream = await openai.responses.create({
model: 'auto',
input: 'Write three release notes bullets for our docs update.',
stream: true,
});
for await (const event of stream) {
if (event.type === 'response.output_text.delta') {
process.stdout.write(event.delta);
}
}
```
```python Python SDK theme={null}
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
stream = sdk.llm.responses.create(
model="auto",
input="Write three release notes bullets for our docs update.",
stream=True,
)
for event in stream:
if event.data.type == "response.output_text.delta":
print(event.data.delta, end="", flush=True)
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Components;
using MeetKai.MKA1.Types.Requests;
var sdk = new SDK(bearerAuth: "Bearer ");
var res = await sdk.Llm.Responses.CreateAsync(new ResponsesCreateRequest()
{
Model = "auto",
Input = ResponsesCreateRequestInput.CreateStr(
"Write three release notes bullets for our docs update."),
Stream = true,
});
```
```bash CLI theme={null}
mka1 llm responses create \
--model auto \
--input '"Write three release notes bullets for our docs update."' \
--stream
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"model": "auto",
"input": "Write three release notes bullets for our docs update.",
"stream": true
}'
```
Use streaming when you want to render partial output as it arrives.
## Long-running requests
Use [background responses](/docs/background-responses) when work must continue after the initial request returns.
# Teams and members
Source: https://docs.mka1.com/docs/teams-and-members
Invite people and organize access within an organization.
## Organize access
MKA1 access is organized as a simple hierarchy: **organization → teams → members**, with **roles** controlling what each person can do and **service accounts** standing in for non-human callers.
### The organization and its owner
When you accept the cluster invite, you become the **owner** of your organization. The owner has full control: Usage metrics, members, teams, and settings. Everyone else you bring in is either an **admin** or a **member**:
| Role | What they can do |
| :- | :- |
| **Owner** | Full control of the organization - usage, members, and settings. |
| **Admin** | Manage members, teams, and API keys across the organization. |
| **Member** | Access their team's models, files, and API keys. |
### Teams
Every organization starts with a **Default** team, and people you invite from the console join it automatically. You can add more teams, and members belong to one or more of them. Teams are where most work and access live: **API keys and agents are scoped to a single team**, while repositories and compute belong to the organization. A key minted on one team grants access only to that team's resources. Moving someone (or a service account) off a team revokes the access that came with it, and keys tied to that team stop working. This makes teams the natural boundary for separating projects, environments, or business units. Manage them under **Access → Teams**, where you can create a team and manage its flat membership roster.
### Inviting teammates
To add a person, send them an **organization invite** by email. You can do this by navigating to **Access → Organizations** and clicking **Invite people** in the top right corner. Share the generated link that opens the **Accept invite** page, which shows the organization, who invited them, the role they'll get, and when the invite expires.
What they do to accept depends on their state:
* **No account yet** (This is the most likely scenario) - they sign up (email/password or Google) with the invited email, verify it, and are dropped back onto the invite to finish joining.
* **Already signed in with the invited email** - one click on **Accept & join** adds them to the organization.
* **Signed in as a different email** - they're prompted to switch to the invited account first, since invites are bound to a specific address.
Invites can expire or be revoked, so send a fresh link if someone reports a dead one.
For production applications, use [service accounts](/docs/service-accounts). For resource-level grants, see [Resource permissions](/docs/authorization).
# Text to speech
Source: https://docs.mka1.com/docs/text-to-speech
Synthesize speech or stream audio as it is generated.
This standalone API speaks text supplied by your application. For speech generated as part of a model reply, see [Audio responses](/docs/audio-responses).
## Generate speech
Use the standard text-to-speech endpoint when you want a complete WAV file.
The response body is binary audio, and the response headers include `X-Language-Code`.
To save the generated audio to history, set `store=true`. When stored, the response also includes `X-Tts-Id`, and persistence completes before the response returns.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
import { writeFileSync } from 'node:fs';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const result = await sdk.llm.speech.speak({
xOnBehalfOf: '',
textToSpeechRequest: {
text: 'Welcome to the MKA1 API speech guide.',
language: 'en',
store: true,
},
});
const audioBuffer = Buffer.from(await new Response(result.result).arrayBuffer());
const languageCode = result.headers['x-language-code']?.[0];
const ttsId = result.headers['x-tts-id']?.[0];
writeFileSync('speech.wav', audioBuffer);
console.log(languageCode);
console.log(ttsId);
```
```python Python SDK theme={null}
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
result = sdk.llm.speech.speak(
text="Welcome to the MKA1 API speech guide.",
language="en",
store=True,
)
with open("speech.wav", "wb") as f:
f.write(result.body)
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Components;
using MeetKai.MKA1.Types.Requests;
var sdk = new SDK(bearerAuth: "Bearer ");
var result = await sdk.Llm.Speech.SpeakAsync(new MeetKai.MKA1.Types.Components.TextToSpeechRequest()
{
Text = "Welcome to the MKA1 API speech guide.",
Language = TextToSpeechRequestLanguage.En,
Store = true,
});
System.IO.File.WriteAllBytes("speech.wav", result.Bytes!);
```
```bash CLI theme={null}
mka1 llm speech speak \
--text 'Welcome to the MKA1 API speech guide.' \
--language en \
--store \
--output-file speech.wav
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/speech/tts \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"text": "Welcome to the MKA1 API speech guide.",
"language": "en",
"store": true
}' \
--output speech.wav
```
## Stream speech for lower latency
Use streaming text-to-speech when you want playback to start before the full audio file is ready.
Choose `mp3` for smaller payloads or `pcm` for uncompressed audio (returned as `audio/wav`).
To save the generated audio to history, set `store=true`. When stored, the response includes `X-Tts-Id`. History persistence for streaming is best-effort and completes shortly after the stream ends, so an immediate lookup by `X-Tts-Id` can briefly return `404`. If persistence fails or is skipped (for example, if the audio exceeds the 25MB history cap), the id is never assigned and lookups keep returning `404`.
```ts TypeScript SDK theme={null}
const result = await sdk.llm.speech.speakStreaming({
xOnBehalfOf: '',
textToSpeechStreamingRequest: {
text: 'Start speaking this response as soon as audio is ready.',
language: 'en',
format: 'mp3',
store: true,
},
});
const contentType = result.headers['content-type']?.[0];
const languageCode = result.headers['x-language-code']?.[0];
const ttsId = result.headers['x-tts-id']?.[0];
console.log(contentType);
console.log(languageCode);
console.log(ttsId);
```
```python Python SDK theme={null}
result = sdk.llm.speech.speak_streaming(
text="Start speaking this response as soon as audio is ready.",
language="en",
format_="mp3",
store=True,
)
with open("speech.mp3", "wb") as f:
f.write(result.body)
```
```csharp C# SDK theme={null}
var result = await sdk.Llm.Speech.SpeakStreamingAsync(new MeetKai.MKA1.Types.Components.TextToSpeechStreamingRequest()
{
Text = "Start speaking this response as soon as audio is ready.",
Language = TextToSpeechStreamingRequestLanguage.En,
Format = TextToSpeechStreamingRequestFormat.Mp3,
Store = true,
});
// Response contains either MP3 or WAV bytes depending on format
var audioBytes = result.TwoHundredAudioMpegBytes ?? result.TwoHundredAudioWavBytes;
System.IO.File.WriteAllBytes("speech.mp3", audioBytes!);
```
```bash CLI theme={null}
mka1 llm speech speak-streaming \
--text 'Start speaking this response as soon as audio is ready.' \
--language en \
--format mp3 \
--store \
--output-file speech.mp3
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/speech/tts/stream \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"text": "Start speaking this response as soon as audio is ready.",
"language": "en",
"format": "mp3",
"store": true
}' \
--output speech.mp3
```
## Supported languages
Set `language` to the language of your text, or leave it as `auto` (the default) to detect it from the text. Both endpoints accept these ISO 639-1 codes:
| Code | Language |
| - | - |
| `en` | English |
| `zh` | Chinese |
| `hi` | Hindi |
| `es` | Spanish |
| `ar` | Arabic |
| `bn` | Bengali |
| `pt` | Portuguese |
| `ru` | Russian |
| `ja` | Japanese |
| `pa` | Punjabi |
| `de` | German |
| `ko` | Korean |
| `fr` | French |
| `tr` | Turkish |
| `it` | Italian |
| `th` | Thai |
| `pl` | Polish |
| `nl` | Dutch |
| `id` | Indonesian |
| `vi` | Vietnamese |
| `ur` | Urdu |
Any other `language` value returns `400 Bad Request`.
With `auto`, `X-Language-Code` reports the language the API detected. If that language is not in the table, the request still succeeds: the text is spoken with the English voice, and `X-Language-Code` is `en`. If your text may be in an unsupported language, check `X-Language-Code` before you use the audio.
# Tracking
Source: https://docs.mka1.com/docs/tracking
Early access
Track experiment parameters and training metrics with MLflow-compatible tools and supported W&B clients.
MKA1 tracking is compatible with MLflow experiment tracking and selected W\&B clients. Use it from any training framework or tool that supports a custom MLflow tracking URI for parameters and metrics.
## Connect to tracking
Use `https://tracking.mka1.com` with an [API key](/docs/authentication) that has `read:tracking` and `write:tracking` scopes.
For MLflow-compatible tools, configure:
```bash MLflow configuration theme={null}
export MLFLOW_TRACKING_URI="https://tracking.mka1.com"
export MLFLOW_TRACKING_TOKEN=""
```
Your existing MLflow integration can then send experiment parameters and metrics to MKA1. Experiments and runs are scoped to your API key's organization and team.
## W\&B compatibility
**Supported versions for metrics logging and run resume:** `wandb>=0.22.0,<0.23.1`.
```bash W&B configuration theme={null}
export WANDB_BASE_URL="https://tracking.mka1.com"
export WANDB_API_KEY=""
```
## Example: log a training run
If your training framework already logs through MLflow, use its existing integration. To log directly from your own code, the equivalent implementation looks like this:
```python MLflow client theme={null}
from mlflow import MlflowClient
client = MlflowClient(tracking_uri="https://tracking.mka1.com")
experiment_name = "training-example"
experiment = client.get_experiment_by_name(experiment_name)
experiment_id = (
experiment.experiment_id
if experiment is not None
else client.create_experiment(experiment_name)
)
run = client.create_run(experiment_id, run_name="loss-example")
run_id = run.info.run_id
client.log_param(run_id, "learning_rate", "0.001")
for step, loss in enumerate([0.8, 0.5, 0.3]):
client.log_metric(run_id, "train/loss", loss, step=step)
client.set_terminated(run_id)
for metric in client.get_metric_history(run_id, "train/loss"):
print(metric.step, metric.value)
```
## Artifacts
Artifact upload, download, and listing are not supported yet. W\&B versioned Artifacts are also unsupported. Store checkpoints, datasets, and model files in [Repositories](/docs/repositories).
# Usage and auditing
Source: https://docs.mka1.com/docs/usage-auditing
Track per-user usage, correlate requests at the API edge, and structure per-unit audit events for misuse detection.
Use this guide when you need to show which account and end user made a request, produce per-user usage reports, and investigate improper actions.
The MKA1 API gives you public usage endpoints, live request correlation headers, and user-linked observability fields.
For endpoint details, see the [API Reference](/api-reference/introduction) and open the **Usage** group.
## What is available today
The live API edge and observability stack expose the following pieces:
* Every API response includes `X-Request-ID` — including rejections (401/429) issued at the gateway edge.
* The gateway ships a global Kong `correlation-id` plugin (part of the platform's deployment configuration, applied on every install) with `header_name: X-Request-ID`, `echo_downstream: true`, and `generator: uuid#counter`. A client-supplied `X-Request-ID` is preserved; requests without one get a generated ID.
* The audit trail records the same ID as `correlation_id` on every audited request — for requests rejected at the edge, the audit shipper resolves it from the echoed response header, so the ID a client quotes from an error response still finds the audit record.
* For requests that reach the gateway, log lines carry the ID as `httpRequestId` (alongside `traceId`/`spanId`) and request traces carry it as the `http.request_id` span attribute — so one ID joins the response header, the audit trail, logs, and traces.
* Live SigNoz logs include `userId`, `externalUserId`, and `userContext`.
* Existing SigNoz assets include the `MKLLM Gateway`, `Guardrail Dashboard`, and `Sandbox Commands` dashboards, plus the `Sandbox Commands 24h`, `Sandbox Command Errors 24h`, and `MKLLM Errors` log views.
Recent examples from live systems:
* `GET /api/v1/llm/responses` returned `X-Request-ID: 0736e48b-3d39-48d8-806c-952c907*****#12`
* `GET /api/v1/agents` returned `X-Request-ID: 0736e48b-3d39-48d8-806c-952c90*****#13`
* SigNoz 24-hour aggregates showed `externalUserId` values such as `docs-pt-br-user` with `14` events and `docs-test-user` with `7` events
* SigNoz 24-hour aggregates showed `userId` values such as `dRdj8VeoyuE7P9txS7ZVQ8ixI2*****` with `63` events and `uy95pqlp4ABgWCn5oLikRGV1TT*****` with `23` events
### What this looks like in our dashboard
## Send a stable end-user ID on every delegated request
For multi-user server-side integrations, send both `Authorization` and `X-On-Behalf-Of`.
This is what ties usage, resources, and logs back to the right end user.
```bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"model": "meetkai:functionary-pt",
"input": "Reply with ok."
}'
```
Capture the response headers from that request and store `X-Request-ID` with your own application log entry.
That gives you a stable join key between the API edge and downstream observability.
## Query per-user usage reports
The public usage endpoints support `external_user_ids` (delegated end-user IDs from `X-On-Behalf-Of`) and `user_ids` (platform user IDs) filters, plus `group_by` dimensions.
Use them for account-level reporting, then use SigNoz logs to investigate a specific end user or request.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const endTime = Math.floor(Date.now() / 1000);
const startTime = endTime - 24 * 60 * 60;
const usage = await sdk.llm.usage.responses({
startTime,
endTime,
externalUserIds: ["docs-test-user", "docs-pt-br-user"],
groupBy: ["model", "background"],
});
console.log(usage);
```
Use `externalUserIds` for your end-user IDs from `X-On-Behalf-Of`.
For example, the live spec currently exposes usage endpoints for responses, conversations, completions, embeddings, extract, classify, and vector stores.
Grouped by `model`, Responses usage reports the name each request sent, such as `auto`, and Completions usage reports the model that served each request. The `models` filter matches the same names. To see which model served a Responses request, read the response's `resolved_model` field (see [Auto routing](/docs/auto-routing#validate-the-selected-model)).
## Register actions as a fixed audit vocabulary
Per-user and per-unit misuse detection depends on your services emitting consistent action events.
The shared audit contract defines the required fields:
* `request_id`
* `actor_id`
* `unit_id`
* `route_name`
* `action`
* `resource_type`
* `resource_id`
* `outcome`
* `policy_action`
```json theme={null}
{
"request_id": "0736e48b-3d39-48d8-806c-952c907aa0be#12",
"actor_id": "docs-test-user",
"unit_id": "support-team-a",
"route_name": "POST /api/v1/llm/responses",
"action": "generate",
"resource_type": "response",
"resource_id": "resp_54d14e822fac430396ea2c04f771d7d3",
"outcome": "success"
}
```
If a policy or guardrail fires, record that in the same event:
```json theme={null}
{
"action": "tool_call",
"outcome": "policy_violation",
"policy_action": "block"
}
```
## Detect improper actions
Group your logs and dashboards on `actor_id`, `unit_id`, `action`, `outcome`, and `policy_action`.
This lets you answer two different questions:
* Which end user or unit generated the activity?
* Which actions were denied, throttled, or blocked by policy?
The audit contract defines these outcomes:
* `success`
* `denied`
* `throttled`
* `validation_error`
* `policy_violation`
The corresponding `policy_action` values are:
* `warn`
* `block`
* `escalate`
A live example already visible in SigNoz on March 30, 2026 shows runtime limiting of tool activity in the gateway:
* message: `Limiting parallel tool calls to respect max_tool_calls`
* `requestedToolCalls: 2`
* `allowedToolCalls: 1`
* `maxToolCalls: 5`
* `responseId: resp_bcc0e8bba9524e8d9c14289c0c6*****`
That pattern is useful for improper-action detection because it shows the attempted action count and the allowed action count in the same event.
## Practical investigation flow
When you investigate a questionable request, use this order:
1. Start with the account-level usage report in the API Reference usage endpoints.
2. Narrow to the end user by `X-On-Behalf-Of` and `externalUserId`.
3. Use `X-Request-ID` to correlate the exact edge request.
4. Inspect SigNoz logs for `userId`, `externalUserId`, `userContext`, `route_name`, `action`, and `outcome`.
5. Check the `MKLLM Gateway`, `Guardrail Dashboard`, and `Sandbox Commands` dashboards for surrounding policy or tool activity.
This gives you a consistent path from usage reporting to a specific request and then to the exact action event that was allowed, warned, blocked, or escalated.
# Vector stores
Source: https://docs.mka1.com/docs/vector-stores
Index files and retrieve relevant document chunks.
Vector stores are reusable retrieval resources. This guide covers their lifecycle and direct search; pass retrieved context into a [Response](/docs/responses) when building an answer grounded in your files.
First [upload your files](/docs/files). Keep their file IDs for the examples below.
## Create a vector store
Create a vector store and attach one or more uploaded file IDs.
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
const vectorStore = await sdk.llm.vectorStores.create({
xOnBehalfOf: '',
createVectorStoreRequest: {
name: 'Support knowledge base',
description: 'Indexed support manuals and help center docs',
fileIds: ['file-abc123'],
expiresAfter: { anchor: 'last_active_at', days: 30 },
},
});
```
```ts OpenAI SDK theme={null}
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: '',
baseURL: 'https://apigw.mka1.com/api/v1/llm/',
defaultHeaders: { 'X-On-Behalf-Of': '' },
});
const vectorStore = await openai.vectorStores.create({
name: 'Support knowledge base',
description: 'Indexed support manuals and help center docs',
file_ids: ['file-abc123'],
expires_after: { anchor: 'last_active_at', days: 30 },
});
```
```python Python SDK theme={null}
from meetkai_mka1 import SDK
sdk = SDK(bearer_auth="Bearer ")
vector_store = sdk.llm.vector_stores.create(
name="Support knowledge base",
description="Indexed support manuals and help center docs",
)
```
```csharp C# SDK theme={null}
using MeetKai.MKA1;
using MeetKai.MKA1.Types.Components;
using MeetKai.MKA1.Types.Requests;
var sdk = new SDK(bearerAuth: "Bearer ");
var vs = await sdk.Llm.VectorStores.CreateAsync(new MeetKai.MKA1.Types.Components.CreateVectorStoreRequest()
{
Name = "Support knowledge base",
Description = "Indexed support manuals and help center docs",
});
```
```bash CLI theme={null}
mka1 llm vector-stores create --body '{
"name": "Support knowledge base",
"description": "Indexed support manuals and help center docs",
"file_ids": ["file-abc123"],
"expires_after": { "anchor": "last_active_at", "days": 30 }
}'
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/vector_stores \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"name": "Support knowledge base",
"description": "Indexed support manuals and help center docs",
"file_ids": [
"file-abc123"
],
"expires_after": {
"anchor": "last_active_at",
"days": 30
}
}'
```
This response returns a vector store ID such as `vs_abc123`.
## Add more files later
You can add more files to an existing vector store without recreating it.
```ts TypeScript SDK theme={null}
const vsFile = await sdk.llm.vectorStores.createFile({
vectorStoreId: 'vs_abc123',
xOnBehalfOf: '',
createVectorStoreFileRequest: {
fileId: 'file-def456',
attributes: { category: 'manual', version: '2.0' },
},
});
```
```ts OpenAI SDK theme={null}
const vsFile = await openai.vectorStores.files.create('vs_abc123', {
file_id: 'file-def456',
});
```
```python Python SDK theme={null}
vs_file = sdk.llm.vector_stores.create_file(
vector_store_id="vs_abc123",
file_id="file-def456",
)
```
```csharp C# SDK theme={null}
// Adding files to an existing vector store is done via the
// VectorStores.CreateFile or VectorStores.Files API methods.
// Refer to the API reference for the full method signature.
```
```bash CLI theme={null}
mka1 llm vector-stores create-file \
--vector-store-id vs_abc123 \
--file-id file-def456 \
--attributes '{"category":"manual","version":"2.0"}'
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/vector_stores/vs_abc123/files \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"file_id": "file-def456",
"attributes": {
"category": "manual",
"version": "2.0"
}
}'
```
The vector store file can return `status: "in_progress"` while indexing runs.
A file is not searchable until its status reaches `"completed"` — searching before then
succeeds but omits the file, so poll for `"completed"` rather than assuming a fixed wait.
Indexing usually finishes in seconds, but latency varies with file size and load.
Check the Files and Vector Stores endpoints in the API Reference for the polling endpoint (for example, `GET /vector_stores/{vector_store_id}/files/{file_id}`).
## Search the vector store
Use semantic search to retrieve the most relevant chunks for a user question.
```ts TypeScript SDK theme={null}
const results = await sdk.llm.vectorStores.search({
vectorStoreId: 'vs_abc123',
xOnBehalfOf: '',
searchVectorStoreRequest: {
query: 'How do I reset my password?',
maxNumResults: 5,
},
});
```
```ts OpenAI SDK theme={null}
const results = await openai.vectorStores.search('vs_abc123', {
query: 'How do I reset my password?',
max_num_results: 5,
});
```
```python Python SDK theme={null}
results = sdk.llm.vector_stores.search(
vector_store_id="vs_abc123",
query="How do I reset my password?",
)
```
```csharp C# SDK theme={null}
// Search is available via the VectorStores.Search method.
// Refer to the API reference for the full method signature.
```
```bash CLI theme={null}
mka1 llm vector-stores search \
--vector-store-id vs_abc123 \
--body '{
"query": "How do I reset my password?",
"max_num_results": 5
}'
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/vector_stores/vs_abc123/search \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"query": "How do I reset my password?",
"max_num_results": 5
}'
```
The response returns ranked matches with `file_id`, `filename`, score data, chunk content, and the file's current `attributes`.
## Filter search by file attributes
Attributes are file-level key-value metadata — string, number, or boolean values — set when you attach a file (see [Add more files later](#add-more-files-later)).
You can change them after ingest with the update-file endpoint (`POST /vector_stores/{vector_store_id}/files/{file_id}`); search always evaluates the current values.
Pass `filters` in the search request to restrict results to files whose attributes match.
A filter is either a comparison — `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin` — or an `and`/`or` compound of nested filters.
```ts TypeScript SDK theme={null}
const results = await sdk.llm.vectorStores.search({
vectorStoreId: 'vs_abc123',
xOnBehalfOf: '',
searchVectorStoreRequest: {
query: 'How do I reset my password?',
maxNumResults: 5,
filters: {
type: 'and',
filters: [
{ type: 'eq', key: 'category', value: 'manual' },
{ type: 'ne', key: 'version', value: '1.0' },
],
},
},
});
```
```ts OpenAI SDK theme={null}
const results = await openai.vectorStores.search('vs_abc123', {
query: 'How do I reset my password?',
max_num_results: 5,
filters: {
type: 'and',
filters: [
{ type: 'eq', key: 'category', value: 'manual' },
{ type: 'ne', key: 'version', value: '1.0' },
],
},
});
```
```python Python SDK theme={null}
results = sdk.llm.vector_stores.search(
vector_store_id="vs_abc123",
query="How do I reset my password?",
filters={
"type": "and",
"filters": [
{"type": "eq", "key": "category", "value": "manual"},
{"type": "ne", "key": "version", "value": "1.0"},
],
},
)
```
```csharp C# SDK theme={null}
// Filtered search is available via the VectorStores.Search method's Filters
// parameter (ComparisonFilter / CompoundFilter).
// Refer to the API reference for the full method signature.
```
```bash CLI theme={null}
mka1 llm vector-stores search \
--vector-store-id vs_abc123 \
--body '{
"query": "How do I reset my password?",
"max_num_results": 5,
"filters": {
"type": "and",
"filters": [
{ "type": "eq", "key": "category", "value": "manual" },
{ "type": "ne", "key": "version", "value": "1.0" }
]
}
}'
```
```bash Bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/vector_stores/vs_abc123/search \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"query": "How do I reset my password?",
"max_num_results": 5,
"filters": {
"type": "and",
"filters": [
{ "type": "eq", "key": "category", "value": "manual" },
{ "type": "ne", "key": "version", "value": "1.0" }
]
}
}'
```
Filter evaluation follows these rules:
* A file that does not have the filter's `key` never matches — including for `ne` and `nin`. A filter only opts a file in on evidence, never by absence.
* `eq` and `ne` are strict equality with no type coercion: the string `"2"` does not equal the number `2`.
* `gt`, `gte`, `lt`, and `lte` compare numbers only; a non-numeric attribute or filter value fails the comparison.
* `in` and `nin` take an array `value` and test whether the file's attribute is (or is not) one of its elements.
* `and` and `or` compounds nest to any depth.
* On [graph stores](/docs/graph-retrieval#create-a-graph-store), filtering is applied after retrieval, so a filtered search can return fewer than `max_num_results` matches.
## Typical workflow
Use this sequence for most retrieval setups:
1. Upload the source file.
2. Create a vector store with `file_ids`, or attach the file later.
3. Wait for file processing to complete (for example, file `status: "processed"`, and vector-store file indexing `status: "completed"`).
4. Search the vector store when you need relevant context.
You can then feed the returned text into your own application logic or a Responses request.
For graph-aware search, see [Graph retrieval](/docs/graph-retrieval).
# MKA1
Source: https://docs.mka1.com/index
Find what you can build with MKA1, explore the services behind it, and meet MKA1 Code.
# List runs for an agent
Source: https://docs.mka1.com/api-reference/agent-runs/list-runs-for-an-agent
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{agent_id}/runs
# Start a saved agent run
Source: https://docs.mka1.com/api-reference/agent-runs/start-a-saved-agent-run
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}/runs
Starts an asynchronous background run for a saved agent and returns the queued run record. Use the run retrieval endpoint to poll status or the events endpoint to stream progress.
# List agent versions
Source: https://docs.mka1.com/api-reference/agent-versions/list-agent-versions
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{agent_id}/versions
Lists the configuration history for an agent. Each committed change (create, update, rollback) appends a version.
# Retrieve an agent version
Source: https://docs.mka1.com/api-reference/agent-versions/retrieve-an-agent-version
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{agent_id}/versions/{version}
# Roll back an agent to a version
Source: https://docs.mka1.com/api-reference/agent-versions/roll-back-an-agent-to-a-version
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}/versions/{version}/rollback
Restores the target version's configuration as a new current version. History is preserved: the restore is appended as a new version rather than deleting later ones.
# Create an agent
Source: https://docs.mka1.com/api-reference/agents/create-an-agent
https://apigw.mka1.com/speakeasy.json post /api/v1/agents
# Delete an agent
Source: https://docs.mka1.com/api-reference/agents/delete-an-agent
https://apigw.mka1.com/speakeasy.json delete /api/v1/agents/{agent_id}
# List agents
Source: https://docs.mka1.com/api-reference/agents/list-agents
https://apigw.mka1.com/speakeasy.json get /api/v1/agents
# Retrieve an agent
Source: https://docs.mka1.com/api-reference/agents/retrieve-an-agent
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{agent_id}
# Update an agent
Source: https://docs.mka1.com/api-reference/agents/update-an-agent
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}
# Create a conversation
Source: https://docs.mka1.com/api-reference/conversations/create-a-conversation
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/conversations
Create a conversation to store and retrieve conversation state across Response API calls.
# Create conversation items
Source: https://docs.mka1.com/api-reference/conversations/create-conversation-items
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/conversations/{conversation_id}/items
Create items in a conversation with the given ID.
# Delete a conversation
Source: https://docs.mka1.com/api-reference/conversations/delete-a-conversation
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/conversations/{conversation_id}
Delete a conversation. Items in the conversation will not be deleted.
# Delete a conversation item
Source: https://docs.mka1.com/api-reference/conversations/delete-a-conversation-item
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/conversations/{conversation_id}/items/{item_id}
Delete an item from a conversation with the given ID.
# Delete multiple conversation items
Source: https://docs.mka1.com/api-reference/conversations/delete-multiple-conversation-items
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/conversations/{conversation_id}/items
Delete multiple items from a conversation with the given ID.
# List conversation items
Source: https://docs.mka1.com/api-reference/conversations/list-conversation-items
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/conversations/{conversation_id}/items
List all items for a conversation with the given ID.
# List conversations
Source: https://docs.mka1.com/api-reference/conversations/list-conversations
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/conversations
List all conversations for the authenticated user with pagination support.
# Retrieve a conversation
Source: https://docs.mka1.com/api-reference/conversations/retrieve-a-conversation
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/conversations/{conversation_id}
Get a conversation by ID.
# Retrieve a conversation item
Source: https://docs.mka1.com/api-reference/conversations/retrieve-a-conversation-item
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/conversations/{conversation_id}/items/{item_id}
Get a single item from a conversation with the given IDs.
# Update a conversation
Source: https://docs.mka1.com/api-reference/conversations/update-a-conversation
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/conversations/{conversation_id}
Update a conversation's metadata.
# Create text embeddings
Source: https://docs.mka1.com/api-reference/embeddings/create-text-embeddings
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/embeddings
Generates vector embeddings for single or multiple text inputs. Returns floating-point vectors along with token usage statistics.
# List available embedding models
Source: https://docs.mka1.com/api-reference/embeddings/list-available-embedding-models
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/embeddings/models
Returns a list of available embedding models with their limits. Use this endpoint to discover which models are available and their constraints (batch size, input length) before making embedding requests.
# Delete file
Source: https://docs.mka1.com/api-reference/files/delete-file
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/files/{file_id}
Delete a file from storage. The file is first removed from every vector store it is attached to, embeddings included, so it no longer appears in vector store search or `file_search` results. If that cannot finish, the file is kept and the request fails; retrying completes the deletion. Returns 400 `feature_unavailable` when the file is attached to a vector store while the search service is unavailable, and 409 when the file was added to a vector store during the deletion.
# List files
Source: https://docs.mka1.com/api-reference/files/list-files
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/files
Returns a list of files that have been uploaded.
# Retrieve file
Source: https://docs.mka1.com/api-reference/files/retrieve-file
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/files/{file_id}
Returns information about a specific file.
# Retrieve file content
Source: https://docs.mka1.com/api-reference/files/retrieve-file-content
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/files/{file_id}/content
Returns the raw binary contents of the specified file with appropriate Content-Type header.
# Upload file
Source: https://docs.mka1.com/api-reference/files/upload-file
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/files
Upload a file that can be used with Assistants, Vector Stores, and other features. Files are uploaded to S3 for durable storage.
# Generate images from text descriptions
Source: https://docs.mka1.com/api-reference/images/generate-images-from-text-descriptions
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/images/generations
Creates AI-generated images from text descriptions.
# API overview
Source: https://docs.mka1.com/api-reference/introduction
## OpenAPI source
This API reference is generated from the live MKA1 OpenAPI specification.
## Base URL
Use `https://apigw.mka1.com` as the primary API server.
## Authentication
Authenticate requests with your MKA1 API key in the `Authorization` header.
For multi-user server-side integrations, also send `X-On-Behalf-Of` to identify
the end user.
```http theme={null}
Authorization: Bearer
X-On-Behalf-Of:
```
# Activate a catalog entry
Source: https://docs.mka1.com/api-reference/models/activate-a-catalog-entry
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/models/registry
Claims a model name from one catalog source. Re-activation from the same source is idempotent; a different holder returns 409.
# Add cluster model access for an organization
Source: https://docs.mka1.com/api-reference/models/add-cluster-model-access-for-an-organization
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/models/catalog/orgs/{org_id}/access
Idempotently adds availability without revoking any model names. Set activate to true to also activate every requested model from the cluster source in the target organization. Grants and activations are atomic per request; a name active from another source returns 409 without changing access or activation. Existing activation audit details are preserved on retries.
# Check a BYO catalog model's health
Source: https://docs.mka1.com/api-reference/models/check-a-byo-catalog-models-health
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/models/catalog/health
Probes an available BYO definition whether or not it is active.
# Clear a cluster-default model price
Source: https://docs.mka1.com/api-reference/models/clear-a-cluster-default-model-price
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/models/pricing
Closes the cluster-default price. Active cluster lineage then uses an org override or becomes unpriced ($0).
# Clear an org price override
Source: https://docs.mka1.com/api-reference/models/clear-an-org-price-override
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/models/pricing/org/{org_id}
Closes a per-org price. Only active cluster lineage can then fall back to the cluster default.
# Clear this org's auto-model override for an endpoint
Source: https://docs.mka1.com/api-reference/models/clear-this-orgs-auto-model-override-for-an-endpoint
https://apigw.mka1.com/speakeasy.json?language=pt-BR delete /api/v1/llm/models/auto/{endpoint}
Remove a substituição por org para o endpoint. As solicitações subsequentes `model: "auto"` passam a utilizar o padrão YAML do operador novamente.
# Deactivate a model registry name
Source: https://docs.mka1.com/api-reference/models/deactivate-a-model-registry-name
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/models/registry
Idempotently removes the active name and closes its org-scope price rows without touching the catalog definition.
# Define a BYO catalog model
Source: https://docs.mka1.com/api-reference/models/define-a-byo-catalog-model
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/models/catalog
Creates an API-owned BYO definition without activating its name.
# Get the cluster currency
Source: https://docs.mka1.com/api-reference/models/get-the-cluster-currency
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/pricing/currency
Returns the single cluster-wide ISO-4217 currency code (null if not set).
# List an organization's cluster model access
Source: https://docs.mka1.com/api-reference/models/list-an-organizations-cluster-model-access
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/catalog/orgs/{org_id}/access
Cluster operator view of an org's available cluster catalog entries and their activation state.
# List an org's price overrides
Source: https://docs.mka1.com/api-reference/models/list-an-orgs-price-overrides
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/pricing/org/{org_id}
Without `model`, lists the org's current overrides. With `model`, returns that override's dated history.
# List available models
Source: https://docs.mka1.com/api-reference/models/list-available-models
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models
Lists the currently available models. Provides basic information about each model including its ID and owner.
# List cluster-default model prices
Source: https://docs.mka1.com/api-reference/models/list-cluster-default-model-prices
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/pricing
Without `model`, lists every model's current cluster-default price. With `model`, returns that model's full dated history.
# List effective prices for the caller's models
Source: https://docs.mka1.com/api-reference/models/list-effective-prices-for-the-callers-models
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/pricing/effective
For every active model, returns its registry-aware price: an org row, a cluster default for cluster lineage, or unpriced ($0). Also lists the `auto` routing alias, priced at the per-metric maximum across every model it can be billed as (`resolves_to`): a judge policy's active candidates, or the direct/YAML target plus any reroute target it can fall through to.
# List organizations with access to a cluster model
Source: https://docs.mka1.com/api-reference/models/list-organizations-with-access-to-a-cluster-model
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/catalog/access
Cluster operator reverse lookup showing availability and activation for one cluster catalog id.
# List the organization's active model registry
Source: https://docs.mka1.com/api-reference/models/list-the-organizations-active-model-registry
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/registry
Single management view of every active name with source-qualified definition, health, price, and activation audit details.
# List the organization's model catalog
Source: https://docs.mka1.com/api-reference/models/list-the-organizations-model-catalog
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/catalog
Lists all BYO, serving, and cluster-access definitions with activation state, blocker, health, and price preview.
# List this org's auto-model overrides
Source: https://docs.mka1.com/api-reference/models/list-this-orgs-auto-model-overrides
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/auto
Returns every endpoint for which this org has set its own `"auto"` target. Endpoints not listed fall through to the operator's YAML defaults.
# Remove a BYO catalog model
Source: https://docs.mka1.com/api-reference/models/remove-a-byo-catalog-model
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/models/catalog
Withdraws a BYO definition and deactivates it only when the active name is sourced from that BYO lineage.
# Replace an organization's cluster model access
Source: https://docs.mka1.com/api-reference/models/replace-an-organizations-cluster-model-access
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/models/catalog/orgs/{org_id}/access
Serializable full replacement; revoked active cluster names are deactivated and their org price rows are closed.
# Retrieve a model
Source: https://docs.mka1.com/api-reference/models/retrieve-a-model
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/models/{model_id}
Retrieves a model instance, providing basic information about the model such as the owner and supported capabilities.
# Set a cluster-default model price
Source: https://docs.mka1.com/api-reference/models/set-a-cluster-default-model-price
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/models/pricing
Upserts the cluster-default price for a model as a new dated version. `rates` is a flexible metric→rate map; omitted metrics are not charged.
# Set an org price override
Source: https://docs.mka1.com/api-reference/models/set-an-org-price-override
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/models/pricing/org/{org_id}
Upserts a dated per-org price. Cluster lineage falls back to the cluster default; BYO and serving lineage become unpriced when no org row exists.
# Set the cluster currency
Source: https://docs.mka1.com/api-reference/models/set-the-cluster-currency
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/models/pricing/currency
Sets the cluster-wide currency. Changing it does not auto-convert existing prices.
# Set this org's auto policy for an endpoint
Source: https://docs.mka1.com/api-reference/models/set-this-orgs-auto-policy-for-an-endpoint
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/models/auto/{endpoint}
Stores either the existing direct `{ endpoint → model_id }` alias or a judge policy with candidate models. Judge routing is supported for responses, completions, transcriptions, and TTS. All configured models must be active when written; revoked candidates are filtered at request time, while an unavailable judge is an explicit error.
# Update a BYO catalog model
Source: https://docs.mka1.com/api-reference/models/update-a-byo-catalog-model
https://apigw.mka1.com/speakeasy.json patch /api/v1/llm/models/catalog
Updates an API-owned BYO definition; yaml-origin entries are file-managed and immutable through this API.
# Cancel an in-progress background response
Source: https://docs.mka1.com/api-reference/responses/cancel-an-in-progress-background-response
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/responses/{response_id}/cancel
Cancels an agent response that is currently processing in the background.
# Compact a conversation
Source: https://docs.mka1.com/api-reference/responses/compact-a-conversation
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/responses/compact
Creates a compacted summary of the conversation history for a response, reducing context size while preserving key information. Returns a compacted response object.
# Create an agent-powered response with tool support
Source: https://docs.mka1.com/api-reference/responses/create-an-agent-powered-response-with-tool-support
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/responses
Creates a new AI agent response using advanced language models with autonomous tool usage capabilities.
# List all responses with pagination
Source: https://docs.mka1.com/api-reference/responses/list-all-responses-with-pagination
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/responses
Retrieves a paginated list of all agent responses for the authenticated user.
# List paginated input items for a response
Source: https://docs.mka1.com/api-reference/responses/list-paginated-input-items-for-a-response
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/responses/{response_id}/input_items
Retrieves a paginated list of all input items provided when creating the specified agent response.
# Permanently delete a response and its data
Source: https://docs.mka1.com/api-reference/responses/permanently-delete-a-response-and-its-data
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/responses/{response_id}
Permanently deletes an agent response and all associated data.
# Retrieve response by ID with status and results
Source: https://docs.mka1.com/api-reference/responses/retrieve-response-by-id-with-status-and-results
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/responses/{response_id}
Retrieves a previously created agent response by its unique ID. When stream=true, returns Server-Sent Events for real-time updates on in-progress background responses.
# Update a response
Source: https://docs.mka1.com/api-reference/responses/update-a-response
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/responses/{response_id}
Update a response's metadata.
# Wake a sleeping background response
Source: https://docs.mka1.com/api-reference/responses/wake-a-sleeping-background-response
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/responses/{response_id}/wake
Interrupts a short sleep tool call on an in-progress background response by providing follow-up input. Wake delivery is polled by the sleeping agent and may take up to one second.
# Delete speech-to-text history item
Source: https://docs.mka1.com/api-reference/speech/delete-speech-to-text-history-item
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/speech/transcriptions/history/{stt_id}
Deletes a stored transcription. The audio blob is content-addressed and may be shared, so it is left in storage.
# Delete text-to-speech history item
Source: https://docs.mka1.com/api-reference/speech/delete-text-to-speech-history-item
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/speech/tts/history/{tts_id}
Deletes a stored text-to-speech generation. The audio blob is content-addressed and may be shared, so it is left in storage.
# Generate LiveKit room token
Source: https://docs.mka1.com/api-reference/speech/generate-livekit-room-token
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/speech/livekit/token
Generates a LiveKit access token for joining a real-time voice room. The token includes encrypted credentials and model configuration for the voice agent.
# List speech-to-text history
Source: https://docs.mka1.com/api-reference/speech/list-speech-to-text-history
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/speech/transcriptions/history
List stored transcriptions for the authenticated user, newest first by default.
# List text-to-speech history
Source: https://docs.mka1.com/api-reference/speech/list-text-to-speech-history
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/speech/tts/history
List stored text-to-speech generations for the authenticated user, newest first by default.
# Retrieve speech-to-text audio
Source: https://docs.mka1.com/api-reference/speech/retrieve-speech-to-text-audio
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/speech/transcriptions/history/{stt_id}/content
Returns the stored input audio for a transcription as a binary response.
# Retrieve speech-to-text history item
Source: https://docs.mka1.com/api-reference/speech/retrieve-speech-to-text-history-item
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/speech/transcriptions/history/{stt_id}
Returns metadata for a stored transcription.
# Retrieve text-to-speech audio
Source: https://docs.mka1.com/api-reference/speech/retrieve-text-to-speech-audio
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/speech/tts/history/{tts_id}/content
Returns the stored audio for a text-to-speech generation as a binary response.
# Retrieve text-to-speech history item
Source: https://docs.mka1.com/api-reference/speech/retrieve-text-to-speech-history-item
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/speech/tts/history/{tts_id}
Returns metadata for a stored text-to-speech generation.
# Speech to text transcription
Source: https://docs.mka1.com/api-reference/speech/speech-to-text-transcription
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/speech/transcriptions
Convert audio to text using advanced speech recognition.
**Complete File Upload (Standard)**
Use `Content-Type: multipart/form-data` to upload the complete audio file in one request. Maximum file size: 25MB.
Example:
```bash
curl -X POST "http://localhost:3000/api/v1/llm/speech/transcriptions?language=en" \
-F "file=@audio.flac"
```
**Chunked Upload (Streaming)**
Use `Transfer-Encoding: chunked` header to stream audio data in chunks as it's being recorded. No need to know total file size upfront. Server buffers chunks until complete before processing. Maximum total size: 25MB.
Example:
```bash
curl -X POST "http://localhost:3000/api/v1/llm/speech/transcriptions?language=en" \
-H "Transfer-Encoding: chunked" \
-H "Content-Type: multipart/form-data" \
--data-binary @audio.flac
```
**Supported Formats:** FLAC, MP3, MP4, MPEG, MPGA, M4A, OGG, WAV, WebM
**Query Parameters:**
- `model` (optional): Transcription model identifier. Defaults to 'auto'.
- `language` (optional): ISO-639-1 or BCP-47 language code (e.g., "en", "en-US"). Auto-detects if not specified.
- `prompt` (optional): Legacy prompt parameter retained for backward compatibility.
- `temperature` (optional): Legacy temperature parameter retained for backward compatibility.
- `include_speaker_data` (optional): When `true`, include speaker diarization data and require WAV/PCM input. Otherwise transcription uses the standard compatibility path.
**Response:** Returns transcribed text in JSON format.
# Streaming text to speech
Source: https://docs.mka1.com/api-reference/speech/streaming-text-to-speech
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/speech/tts/stream
Convert text to speech with real-time streaming audio delivery.
**Key Features:**
- Low-latency audio streaming - playback can start immediately as chunks arrive
- Automatic language detection
- Multiple format support: MP3 or PCM/WAV
- High-quality audio: 24kHz sample rate, 16-bit mono
**Request Body:**
- `text`: Input text to convert to speech - required
- `language`: Language code (default: "auto") - "auto" for automatic detection, or one of the supported ISO 639-1 codes: en, zh, hi, es, ar, bn, pt, ru, ja, pa, de, ko, fr, tr, it, th, pl, nl, id, vi, ur, uk
- `format`: Audio format (default: "mp3") - "mp3" for compressed MPEG audio (96 kbps) or "pcm" for uncompressed WAV
- `model`: TTS model identifier (default: "auto") - "auto" selects the default provider; a registry-resolvable id dispatches to the matching provider (note: not all providers support `format: "mp3"`)
**Response:**
- Streams audio chunks in real-time
- Returns `X-Language-Code` header with detected/used language
- Content-Type: `audio/mpeg` (MP3) or `audio/wav` (PCM)
- When `store` is `true`, returns the `X-Tts-Id` header with the id the history record will be stored under; persistence is best-effort and completes shortly after the stream ends
**Use Cases:**
- Real-time applications requiring immediate audio playback
- Interactive voice responses
- Low-latency text-to-speech scenarios
# Text to speech
Source: https://docs.mka1.com/api-reference/speech/text-to-speech
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/speech/tts
Convert text to speech with automatic language detection.
**Request Body:**
- `text`: Input text to convert to speech - required
- `language`: Language code (default: "auto") - "auto" for automatic detection, or one of the supported ISO 639-1 codes: en, zh, hi, es, ar, bn, pt, ru, ja, pa, de, ko, fr, tr, it, th, pl, nl, id, vi, ur, uk
- `model`: TTS model identifier (default: "auto") - "auto" selects the default provider; a registry-resolvable id dispatches to the matching provider
**Response:** Returns audio file in WAV format with X-Language-Code header. When `store` is `true`, the generation is persisted before the response returns and the new history record id is included in the X-Tts-Id header.
# Classify text into predefined categories
Source: https://docs.mka1.com/api-reference/text-classification/classify-text-into-predefined-categories
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/classify
Classifies text content into one of the provided predefined labels.
# Add a file to a vector store
Source: https://docs.mka1.com/api-reference/vector-stores/add-a-file-to-a-vector-store
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/vector_stores/{vector_store_id}/files
Adds a file to a vector store for semantic search indexing. Returns 410 once the vector store has expired.
# Batch add multiple files to vector store
Source: https://docs.mka1.com/api-reference/vector-stores/batch-add-multiple-files-to-vector-store
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/vector_stores/{vector_store_id}/file_batches
Adds multiple files to a vector store in a single batch operation. Returns 410 once the vector store has expired.
# Cancel batch file processing
Source: https://docs.mka1.com/api-reference/vector-stores/cancel-batch-file-processing
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/vector_stores/{vector_store_id}/file_batches/{batch_id}/cancel
Cancels an in-progress file batch operation. Returns 410 once the vector store has expired.
# Create a vector store
Source: https://docs.mka1.com/api-reference/vector-stores/create-a-vector-store
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/vector_stores
Creates a new vector store for storing and searching through document embeddings.
# Delete a vector store
Source: https://docs.mka1.com/api-reference/vector-stores/delete-a-vector-store
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/vector_stores/{vector_store_id}
Permanently deletes a vector store and its associated embeddings.
# List files in a batch
Source: https://docs.mka1.com/api-reference/vector-stores/list-files-in-a-batch
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/vector_stores/{vector_store_id}/file_batches/{batch_id}/files
Retrieves a paginated list of all files within a specific batch operation. Returns 410 once the vector store has expired.
# List files in a vector store
Source: https://docs.mka1.com/api-reference/vector-stores/list-files-in-a-vector-store
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/vector_stores/{vector_store_id}/files
Retrieves a paginated list of all files in a specific vector store. Returns 410 once the vector store has expired.
# List vector stores
Source: https://docs.mka1.com/api-reference/vector-stores/list-vector-stores
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/vector_stores
Retrieves a paginated list of all vector stores for the authenticated user.
# Modify a vector store
Source: https://docs.mka1.com/api-reference/vector-stores/modify-a-vector-store
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/vector_stores/{vector_store_id}
Updates the properties of an existing vector store. Returns 410 once the vector store has expired.
# Remove file from vector store
Source: https://docs.mka1.com/api-reference/vector-stores/remove-file-from-vector-store
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/vector_stores/{vector_store_id}/files/{file_id}
Removes a file from a vector store and deletes its associated embeddings. If the file is no longer attached but the vector store still holds embeddings for it (for example, left behind by an earlier file deletion), those embeddings are deleted and the request succeeds, provided the file was deleted or you can read it; otherwise, and when there is nothing to remove, returns 404. Returns 409 if the file keeps being added back to the vector store while it is being removed; retrying completes the removal. Returns 410 once the vector store has expired.
# Retrieve a vector store
Source: https://docs.mka1.com/api-reference/vector-stores/retrieve-a-vector-store
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/vector_stores/{vector_store_id}
Retrieves a vector store by its ID. Returns 410 once the vector store has expired.
# Retrieve a vector store file
Source: https://docs.mka1.com/api-reference/vector-stores/retrieve-a-vector-store-file
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/vector_stores/{vector_store_id}/files/{file_id}
Retrieves detailed information about a specific file within a vector store. Returns 410 once the vector store has expired.
# Retrieve file batch status
Source: https://docs.mka1.com/api-reference/vector-stores/retrieve-file-batch-status
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/vector_stores/{vector_store_id}/file_batches/{batch_id}
Retrieves the status of a specific file batch operation within a vector store. Returns 410 once the vector store has expired.
# Retrieve parsed file content
Source: https://docs.mka1.com/api-reference/vector-stores/retrieve-parsed-file-content
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/vector_stores/{vector_store_id}/files/{file_id}/content
Retrieves the complete parsed contents of a file within a vector store. Returns 410 once the vector store has expired.
# Search a vector store
Source: https://docs.mka1.com/api-reference/vector-stores/search-a-vector-store
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/vector_stores/{vector_store_id}/search
Performs semantic search within a vector store to find the most relevant document chunks for a query. Returns 410 once the vector store has expired.
# Update file attributes
Source: https://docs.mka1.com/api-reference/vector-stores/update-file-attributes
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/vector_stores/{vector_store_id}/files/{file_id}
Updates the metadata attributes attached to a file within a vector store. Returns 410 once the vector store has expired.
# Authorship and provenance
Source: https://docs.mka1.com/docs/authorship-procedure
The procedure for updating authorship with each new version.
The following is the procedures set up in our infrastructure repository for updating copyright information with each new version. We have an AUTHORS.md file, NOTICE.md file, as well as procedures for our audit log and releases.
## Full code
AUTHORS.md:
```
# Authors
This file records release-level authorship acknowledgements for `infra-resources`.
Update it as part of the formal release procedure documented in `compliance/governance/release-ip-procedure.md`.
## Current project owner
- MeetKai
```
NOTICE.md:
```
# Notice
This repository contains configuration, deployment manifests, and documentation for MeetKai infrastructure.
Third-party software remains subject to its own license and notice requirements.
Release reviewers must confirm whether new third-party notices are required for each version and record that review in `compliance/governance/release-ip-ledger.csv`.
```
compliance/README.md:
```
This directory collects the repo-owned controls and evidence procedures.
## What is implemented here
- `tools/compliance/capture_no_telemetry.sh`: runs the no-telemetry overlay and records packet capture plus Kubernetes state.
- `tools/compliance/verify_tls13.sh`: proves public endpoints negotiate TLS 1.3 and records ciphers and certificate details.
- `tools/compliance/verify_storage_encryption.sh`: captures EKS secrets encryption and storage encryption settings.
- `tools/compliance/verify_ai_marking.sh`: records response headers that prove AI marking at the API edge.
- `helm/kyverno/`: admission policy that rejects unsigned images.
- `compliance/audit-log-contract.md`: shared event contract for per-user and per-unit audit pipelines.
- `compliance/governance/`: formal release authorship and copyright procedure.
```
compliance/audit-log-contract.md:
```
# Audit event contract
This repo can standardize gateway-side correlation and route metadata.
## Required fields
- `request_id`: propagated from Kong `X-Request-ID`
- `actor_id`: end user or service principal
- `unit_id`: organizational unit or tenant
- `route_name`: logical API route name
- `action`: create, read, update, delete, generate, tool_call, or admin action
- `resource_type`: conversation, response, file, vector_store, prompt, or service-specific type
- `resource_id`: stable identifier for the affected object
- `outcome`: success, denied, throttled, validation_error, or policy_violation
- `policy_action`: warn, block, or escalate when misuse detection triggers
## Infra-owned behavior
- Kong emits `X-Request-ID` on AI and search routes.
- Kong adds `X-AI-Generated` headers on AI generation routes.
- SigNoz dashboards should group on `actor_id`, `unit_id`, `route_name`, and `outcome` once services emit these dimensions.
```
compliance/governance/release-ip-procedure.md:
```
# Release authorship and copyright procedure
This procedure covers bid requirement `4.25`.
Git history alone is not treated as sufficient evidence for authorship updates.
Each release must produce a small set of explicit records.
## Required release records
1. Update `AUTHORS.md` when a new contributor or organization materially contributes to the release.
2. Review `NOTICE.md` for third-party notices or attribution changes.
3. Add a row to `compliance/governance/release-ip-ledger.csv` for the version being released.
4. Store the signed release evidence bundle produced by `tools/compliance/render_evidence_bundle.sh`.
5. Link the release tag or PR in the ledger entry so the review trail is explicit.
## Required reviewer assertions
The release reviewer confirms all of the following for the version:
- authorship additions or removals were reviewed
- third-party notices were reviewed
- any generated documentation or compliance evidence reflects the current release
- the release PR contains the final evidence locations
## Verification
`tools/compliance/check_release_governance.sh` validates that the required files exist and that the release ledger has a non-header entry for the target version.
```
# Retrieval quality
Source: https://docs.mka1.com/docs/evaluating-text-stores
Benchmark results for the MKA1 retrieval engine on the BEIR SciFact dataset: accuracy, latency, and indexing throughput.
This report benchmarks the MKA1 retrieval engine against a standard information retrieval dataset.
It demonstrates RAG-grade retrieval under high document volume — indexing thousands of documents, running hundreds of labeled queries, and measuring accuracy and latency at each stage of the pipeline.
The benchmark uses [SciFact](https://huggingface.co/datasets/BeIR/scifact) from the BEIR benchmark suite — 5,183 scientific abstracts with 300 test queries and human-annotated relevance judgments.
All embeddings were generated with `auto` (4,096 dimensions).
Two configurations of the retrieval engine were measured:
* **Hybrid store** ("Text Store"): zero-configuration storage with automatic hybrid retrieval — vector similarity combined with full-text search.
* **Typed table** ("Tables"): an explicit schema (document ID, content, 4,096-dimension vector) with pure vector search under cosine distance.
Applications access this engine through the platform's [vector stores](/docs/files-and-vector-stores), which add file ingestion, chunking, tenancy, and usage metering on top. The numbers below measure the retrieval engine itself.
## Results summary
A retrieval query goes through two stages: **embedding inference** (converting the query text to a vector) and **database search** (finding the nearest vectors in the store). The total response time is the sum of both.
| Metric | Text Store | Tables |
| - | - | - |
| **NDCG\@10** | 72.4 | 71.8 |
| **Recall\@10** | 83.1 | 82.6 |
| **MRR\@10** | 68.9 | 68.3 |
| Latency | Text Store | Tables |
| - | - | - |
| **Embedding inference** (per query) | 12 ms | 12 ms |
| **Database search p50** (server-side) | 8 ms | 6 ms |
| **Database search p95** (server-side) | 14 ms | 11 ms |
| **End-to-end response p50** (network + embed + search) | 45 ms | 38 ms |
| **End-to-end response p95** (network + embed + search) | 82 ms | 71 ms |
| **Indexing throughput** (5,183 docs) | 182 docs/sec | 166 docs/sec |
The database search latency is reported by the server itself and excludes network overhead and embedding inference. The end-to-end response time includes everything a client would measure.
## Methodology
**Dataset.** The full SciFact corpus and test split: 5,183 scientific abstracts, 300 scientific-claim queries, and the official binary relevance judgments (every one of the 300 queries carries labels).
**Embeddings.** Every document (title + abstract) and every query was embedded with the `auto` embedding model (4,096 dimensions) through the platform embeddings API, in batches of 64. Corpus embedding averaged 8.2 ms per document; query embedding inference measured 12 ms per query.
**Indexing.** The same corpus and the same pre-computed embeddings were indexed into both engine configurations in batches of 100 documents. Indexing throughput was measured over the full 5,183-document run: 182 docs/sec for the hybrid store and 166 docs/sec for the typed table.
**Query execution.** All 300 queries ran against each configuration, retrieving the top 10 results. Two latencies were recorded per query: the server-reported database search time (pure engine time, no network) and the client-observed end-to-end response time. The tables above report p50/p95 across all 300 queries.
**Scoring.** Retrieved rankings were scored against the relevance judgments with the standard BEIR metrics — NDCG\@10, Recall\@10, and MRR\@10 — computed per query and averaged over all queries with labels.
## Interpreting the results
### Accuracy context
The BEIR leaderboard reports NDCG\@10 on SciFact for reference:
| Model | NDCG\@10 |
| - | - |
| BM25 (lexical baseline) | \~66.5 |
| text-embedding-ada-002 | \~70–73 |
| text-embedding-3-large | \~74–76 |
| State-of-the-art (2024) | \~78–80 |
NDCG\@10 scores in the 70–76 range indicate strong retrieval quality, competitive with leading embedding models.
### What to look for
* **NDCG\@10** is the primary metric. It penalizes relevant documents that appear at lower ranks.
* **Recall\@10** measures how many relevant documents appear in the top 10 at all — important for RAG pipelines where downstream generation depends on retrieval completeness.
* **MRR\@10** measures how quickly the first relevant result appears — important for user-facing search.
* **Hybrid vs pure vector**: the hybrid configuration combines vector similarity with full-text keyword matching automatically; the pure-vector configuration trades that for slightly lower search latency. Their accuracy on this dataset is nearly identical — hybrid retrieval's advantage grows on corpora where exact terms matter (names, codes, rare tokens).
### Reading the latency breakdown
A retrieval query has three latency components:
1. **Embedding inference** — the time to convert the query text into a vector. This is model inference and is the same regardless of storage configuration.
2. **Database search** — the time the engine spends finding nearest vectors, as reported by the server. This is pure search time with no network overhead.
3. **End-to-end response** — what the client observes: network round-trip + gateway routing + database search.
If end-to-end latency is high but database search is fast, the bottleneck is network or gateway overhead.
Database search itself can be tuned further with approximate vector indexes when corpora grow much larger.
## See also
* [Files and vector stores](/docs/files-and-vector-stores) — the platform retrieval surface applications build on, including file ingestion, chunking, and search.
* [GraphRAG evaluation](/docs/graphrag) — graph-aware retrieval benchmarked against flat RAG on multi-hop questions.
# GitOps and rollback
Source: https://docs.mka1.com/docs/gitops-atomic-rollback
How MKA1 uses Git as the single source of truth and Helm atomic deploys to guarantee automatic rollback on failure.
MKA1 follows a GitOps-aligned deployment model where the Git repository is the single source of truth for all infrastructure and application state.
Every deployment is an atomic Helm transaction: if any resource fails to become healthy, the entire release rolls back automatically with no manual intervention.
## What is active
### Git as the single source of truth
The entire MKA1 platform is defined as a single Helm chart (`mka1-platform`) stored in the `infra-resources` Git repository.
No change reaches a cluster without first being committed and reviewed via pull request.
* **Helm chart and values files** define every workload, service, secret template, HPA, and PDB for the platform.
* **Environment-specific overrides** separate staging and production configuration while sharing the same chart definition.
* **Encrypted secrets** are managed with SOPS and committed alongside the chart, ensuring that even sensitive configuration is tracked in Git history.
### Atomic Helm deploys
Helm releases are executed with the `--atomic` flag, which wraps the entire upgrade in a transaction.
If any resource in the release fails its readiness check, Helm automatically rolls the entire release back to the previous known-good revision.
```bash theme={null}
helm upgrade --install mka1 mka1-platform \
--atomic \
--wait \
--timeout 15m \
-f values.yaml
```
* **`--atomic`** -- If the upgrade fails at any point, Helm deletes the new resources and restores the previous release. The cluster never stays in a partially deployed state.
* **`--wait`** -- Helm waits for all Pods, Services, and other resources to report ready before marking the release as successful.
* **`--timeout 15m`** -- A configurable ceiling prevents deployments from hanging indefinitely. If readiness is not achieved within the window, the release is treated as failed and rolled back.
### Automated reconciliation via CI/CD
GitHub Actions workflows trigger automatically on every push to `main` that modifies infrastructure paths.
The pipeline authenticates with AWS, configures `kubectl` for the target EKS cluster, and applies the Git-defined desired state:
1. A developer merges a pull request into `main`.
2. GitHub Actions detects the change and triggers the deployment workflow.
3. The workflow checks out the repository at the merged commit SHA.
4. `helm upgrade --install --atomic` reconciles the cluster to match the desired state defined in Git.
5. If the desired state cannot be reached, the atomic rollback guarantees the cluster remains on the last successful revision.
### Immutable deployment history
Every Helm release creates a versioned revision stored in the cluster.
This provides a complete audit trail of what was deployed, when, and from which Git commit.
```bash theme={null}
helm history mka1-platform
helm rollback mka1-platform
```
Combined with Git commit history, this gives full traceability from code change to deployed state.
## How we validate it
We validate the GitOps workflow by inspecting the deployed Helm release state and confirming it matches the Git-defined configuration.
```bash theme={null}
helm list
kubectl rollout status deployment/
helm get values mka1-platform
```
The CI/CD pipeline itself serves as continuous validation: every push to `main` triggers a full reconciliation cycle.
If the cluster state drifts from the Git-defined desired state, the next pipeline run corrects it.
## Evidence
### Helm atomic upgrade flow
The following demonstrates the atomic deploy behavior.
When all resources become healthy, the release succeeds:
```text theme={null}
Release "mka1-platform" has been upgraded. Happy Helming!
NAME: mka1-platform
LAST DEPLOYED: 2026-04-01 18:32:05
NAMESPACE: default
STATUS: deployed
REVISION: 42
```
When a resource fails its readiness check, the entire release is automatically rolled back:
```text theme={null}
Error: UPGRADE FAILED: release mka1-platform failed, and has been rolled back
due to atomic being set: timed out waiting for the condition
```
No partial state is left behind -- the cluster remains on the previous healthy revision.
### Helm release history
```text theme={null}
REVISION UPDATED STATUS DESCRIPTION
40 2026-03-28 14:10:22 superseded Upgrade complete
41 2026-03-30 09:45:11 superseded Upgrade complete
42 2026-04-01 18:32:05 deployed Upgrade complete
```
Each revision is a point-in-time snapshot of the deployed configuration, enabling instant rollback to any previous state.
# GraphRAG
Source: https://docs.mka1.com/docs/graphrag
A benchmark comparison of GraphRAG and traditional RAG on multi-hop retrieval questions.
This evaluation compares GraphRAG with traditional RAG on the same benchmark corpus and the same question set.
The goal was to measure whether graph-aware retrieval improved multi-hop question answering.
## What was implemented
The evaluated system did not use flat chunk retrieval alone.
It implemented GraphRAG with these stages:
1. Split source documents into chunks.
2. Extract entities and relationships from those chunks.
3. Build a knowledge graph from the extracted entities and relationships.
4. Run standard retrieval to get seed evidence for a user question.
5. Expand through graph links to collect connected evidence.
6. Re-rank the final evidence set before answer generation.
That is the GraphRAG behavior that was evaluated.
## What it was compared against
The comparison used a traditional RAG baseline with the same corpus and the same answer model.
The only difference between the two runs was retrieval mode:
* **Baseline RAG**: flat chunk retrieval only
* **GraphRAG**: graph-seeded expansion plus graph-aware reranking
This matters because it isolates the effect of GraphRAG itself.
## Benchmark design
The benchmark was designed to test multi-hop retrieval rather than simple one-chunk lookup.
It used:
* three target knowledge graphs
* nine semantically similar distractor graphs
* 108 short factual documents
* 24 questions that required linking facts across multiple chunks
This design is important.
If every answer already appears in one obvious chunk, GraphRAG will not show much benefit over standard RAG.
## Evaluation method
Both retrieval modes were run over the same benchmark corpus and the same question set.
Both then used the same answer-generation model and the same answer prompt.
The evaluation recorded three metrics:
* **Exact match**: whether the final answer exactly matched the gold answer
* **Token F1**: token overlap between the final answer and the gold answer
* **Evidence recall\@5**: how much of the required supporting evidence appeared in the top 5 retrieved chunks
## How the evaluation was run
The evaluated flow was simple, and identical for both runs — the same store, the same documents, and the same question set.
Only the retrieval mode changed.
1. **Create a graph-enabled store.** The store was configured with an embedding model, an entity/relationship extraction model, a chunk size of 800 tokens with 120 overlap, and a maximum graph traversal depth of 2 hops.
2. **Ingest the corpus.** Each of the 108 benchmark documents was chunked and embedded, and entities and relationships were extracted from every chunk to build the knowledge graph. For example, "Rivera Logistics won the Northern Bridge Sensors contract" and "Atlas Infrastructure Group owns Rivera Logistics" come from different documents, but extraction links them through the shared `Rivera Logistics` entity.
3. **Run every question in baseline mode.** Flat retrieval: embed the question, retrieve the top-scoring chunks, and answer from them.
4. **Run every question in graph mode.** Same question, same store: retrieve seed chunks, identify the seed entities they mention, expand up to 2 hops through the graph to collect connected evidence, and re-rank the expanded evidence set with graph signals before answering.
Step 3 versus step 4 is the key comparison.
The query, corpus, and answer model stayed the same — only the retrieval mode changed:
* **baseline** = traditional flat retrieval
* **graph** = graph-seeded expansion plus graph-aware reranking
## Measured results
The live benchmark run produced the following results:
| Method | Exact Match | Token F1 | Evidence Recall\@5 |
| - | -: | -: | -: |
| Baseline RAG | 25.0% | 27.1% | 55.9% |
| GraphRAG | 62.5% | 62.5% | 71.9% |
Improvement:
* **Exact Match**: `+37.5` points
* **Token F1**: `+35.4` points
* **Evidence Recall\@5**: `+16.0` points
## Acceptance threshold
The benchmark used the following pass criteria:
* exact match improvement of at least `+5.0` points
* evidence recall\@5 improvement of at least `+10.0` points
The evaluated GraphRAG implementation passed both thresholds.
## Representative question-level outcomes
Examples where GraphRAG succeeded and baseline RAG did not:
* "Who is the chief financial officer of the company that owns the Northern Bridge Sensors contract winner?"
* Baseline RAG: `unknown`
* GraphRAG: `Javier Nanda`
* "Which company acquired the firm that prepared a risk report for Meridian Ports Authority?"
* Baseline RAG: `unknown`
* GraphRAG: `Atlas Infrastructure Group`
* "Which company owns the company that won the Delta Reach Sensors contract?"
* Baseline RAG: `unknown`
* GraphRAG: `Bluepeak Transit Group`
These are multi-hop questions.
They require linking facts across connected entities rather than retrieving a single directly matching chunk.
## Why GraphRAG performed better
Baseline RAG retrieved semantically similar chunks, but it sometimes failed to retrieve the connected evidence needed to complete the reasoning chain.
GraphRAG improved performance by:
* identifying the relevant seed entities from the question
* traversing graph relationships to find linked evidence
* reranking the final evidence set with graph signals in addition to semantic similarity
That is why the improvement appears most clearly on multi-hop questions.
## Summary
On this benchmark, GraphRAG outperformed traditional RAG on both final-answer accuracy and supporting-evidence retrieval.
The strongest gains appeared on questions that required linking facts across multiple connected entities.
In the MKA1 platform, graph-aware retrieval is delivered through [vector stores](/docs/files-and-vector-stores) — the platform's retrieval surface, which owns tenancy, usage metering, and billing — as a retrieval mode alongside semantic and hybrid search, rather than as a separate product API.
To turn it on, create a store with `retrieval_mode: "graph"`. See [Create a graph store](/docs/files-and-vector-stores#create-a-graph-store) for the full request and for what changes once a store is in graph mode.
# Localization and ambiguity
Source: https://docs.mka1.com/docs/localization-and-ambiguity
Run neutral evaluations that prove spontaneous regional localization and clarification behavior with the MKA1 SDK.
This guide shows how to evaluate two model behaviors in a way that is reproducible and easy to adapt:
* inferring locale context from the user prompt alone
* asking for clarification when the user prompt is ambiguous
The worked example in this document uses Brazilian Portuguese (`pt-BR`).
The same method can be reused for other locales by changing the prompt set and the scoring signals.
Run every case as a fresh single-turn request.
Do not preload examples that teach the model the exact behavior you plan to score.
## Evaluation principles
Use the same setup for both evaluations:
* Keep the request neutral.
* Do not explicitly instruct the model to localize to a region.
* Do not explicitly instruct the model to ask for clarification.
* Record the exact prompt and the exact raw response for every case.
* Score the output against visible behavioral signals, not against hidden intent.
For locale evaluation, the question is: can the model infer local conventions from the user input alone?
For ambiguity evaluation, the question is: can the model recognize missing context from the user input alone?
## Minimal harness
Use the MKA1 SDK and keep the request shape simple:
```ts TypeScript SDK theme={null}
import { SDK } from '@meetkai/mka1';
import type { ResponseObject } from '@meetkai/mka1/models/components';
const sdk = new SDK({ bearerAuth: 'Bearer ' });
async function runCase(testCase: {
id: string;
capability: 'locale-context' | 'ambiguity';
type: string;
prompt: string;
}) {
const response = await sdk.llm.responses.create({
xOnBehalfOf: '', // optional — attribute the request to one of your end users
responsesCreateRequest: {
model: 'meetkai:functionary-pt',
input: testCase.prompt,
stream: false,
metadata: {
capability: testCase.capability,
eval_case: testCase.id,
eval_type: testCase.type,
},
},
}) as ResponseObject;
return {
...testCase,
outputText: response.outputText,
};
}
```
## Evaluate locale context inference
### Goal
Prove that the model can infer regional conventions from the user prompt alone and apply them naturally when the topic calls for them.
In the `pt-BR` example, the most visible signals are:
* `R$` and Brazilian money formatting
* `dd/mm/yyyy` when the model turns a date into numeric form
* metric units such as `km`, `°C`, and `m`
* correct handling of local idioms and regional expressions
* local social context such as `CPF`, `RG`, and `comprovante de residência`
### Step 1: choose observable locale signals
Pick signals that are easy for a reviewer to see directly in the output.
| Signal type | Generic evidence | Brazil `pt-BR` example |
| - | - | - |
| currency | local currency symbol and numeric style | `R$ 700,00` |
| date | local short date format | `05/04/2026` |
| units | local measurement conventions | `431 km`, `30°C`, `1,73 metro` |
| idioms | correct local meaning and usage | `dar um jeitinho`, `pagar mico`, `ficar de boa` |
| social norms | local documents, institutions, and expectations | `CPF`, `RG`, banking docs |
| regional context | local food, geography, or cultural references | Nordeste brasileiro, São Paulo, Manaus |
### Step 2: run a focused prompt set
The following `pt-BR` prompts are based on real examples from earlier evaluation runs.
They work well because they expose visible local signals without explicitly asking the model to localize.
```ts TypeScript SDK theme={null}
const localeCases: Parameters[0][] = [
{
id: 'locale-currency-lunch',
capability: 'locale-context',
type: 'currency',
prompt: 'Quanto custa em média um almoço em um restaurante popular em São Paulo?',
},
{
id: 'locale-metric-distance',
capability: 'locale-context',
type: 'metric_units',
prompt: 'Qual a distância entre São Paulo e Rio de Janeiro?',
},
{
id: 'locale-metric-temperature',
capability: 'locale-context',
type: 'metric_units',
prompt: 'Qual a temperatura média em Manaus durante o verão?',
},
{
id: 'locale-social-banking',
capability: 'locale-context',
type: 'social_norms',
prompt: 'Preciso abrir uma conta bancária. Quais documentos são necessários?',
},
{
id: 'locale-idiom-jeitinho',
capability: 'locale-context',
type: 'idioms',
prompt: 'O que significa a expressão "dar um jeitinho"?',
},
{
id: 'locale-idiom-ficar-de-boa',
capability: 'locale-context',
type: 'idioms',
prompt: 'Me explique o que quer dizer "ficar de boa".',
},
{
id: 'locale-idiom-pagar-mico',
capability: 'locale-context',
type: 'idioms',
prompt: 'Use a expressão "pagar mico" em uma frase de exemplo.',
},
{
id: 'locale-regional-food',
capability: 'locale-context',
type: 'regionalism',
prompt: 'Quais são as comidas típicas do Nordeste brasileiro?',
},
{
id: 'locale-date-short',
capability: 'locale-context',
type: 'date',
prompt: 'Minha consulta ficou para cinco de abril de 2026 às duas e meia da tarde. Pode resumir isso em uma linha?',
},
];
for (const testCase of localeCases) {
const result = await runCase(testCase);
console.log(JSON.stringify(result));
}
```
If you include time-sensitive prompts such as current fuel price or current minimum wage, record the test date and score factual freshness separately from locale behavior.
### Step 3: score each response
Score each case as `pass`, `partial`, or `fail`.
| Type | Pass | Partial | Fail |
| - | - | - | - |
| currency | Uses the correct local currency symbol and formatting naturally | Local currency is present but formatting is inconsistent | Uses the wrong currency or wrong locale formatting |
| date | Uses the correct local short date format or a clearly local equivalent | Date is understandable but does not show the local format clearly | Uses a conflicting locale format |
| metric units | Uses the expected local units naturally | Correct answer but unit style is vague | Uses the wrong regional units |
| idioms | Explains the idiom with the right local meaning and tone | Roughly correct but culturally thin | Misreads or flattens the idiom |
| social norms | Uses local institutions, documents, or norms when relevant | Mostly right but misses the strongest local markers | Gives generic advice with no local grounding |
| regional context | Grounds the answer in the local region naturally | Correct but generic | Misses or questions the regional context unnecessarily |
### Step 4: assemble the evidence
Your evidence package should show raw outputs that make the locale inference visible.
In the Brazil `pt-BR` example, a compact evidence table can look like this:
| Case | Prompt | What the response proves |
| - | - | - |
| `locale-currency-lunch` | `Quanto custa em média um almoço em um restaurante popular em São Paulo?` | The model inferred Brazil and answered in `R$` without being told to use Brazilian currency |
| `locale-date-short` | `Minha consulta ficou para cinco de abril de 2026 às duas e meia da tarde. Pode resumir isso em uma linha?` | The model converted the date into a Brazilian format without explicit formatting instructions |
| `locale-metric-distance` | `Qual a distância entre São Paulo e Rio de Janeiro?` | The model used `km` rather than miles |
| `locale-idiom-jeitinho` | `O que significa a expressão "dar um jeitinho"?` | The model interpreted a Brazilian idiom with the right cultural nuance |
| `locale-social-banking` | `Preciso abrir uma conta bancária. Quais documentos são necessários?` | The model surfaced Brazilian banking documents such as `CPF`, `RG`, and `comprovante de residência` |
A practical pass condition is:
* at least one strong passing example for currency, date, units, idioms, and social context
* no prompt contains explicit localization coaching
* the raw outputs visibly show local conventions
## Evaluate ambiguity handling
### Goal
Prove that the model recognizes ambiguity in the user prompt and asks a targeted follow-up question instead of guessing.
The evaluation should measure both sides of the behavior:
* whether the model asks for clarification when the prompt is genuinely ambiguous
* whether the model answers directly when the prompt is already clear
### Step 1: build ambiguous prompts and clear controls
The following prompts are based on real examples from earlier evaluation runs.
```ts TypeScript SDK theme={null}
const ambiguityCases: Parameters[0][] = [
{
id: 'ambiguity-lexical-banco',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Preciso de um banco.',
},
{
id: 'ambiguity-lexical-pena',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Quero saber mais sobre pena.',
},
{
id: 'ambiguity-underspecified-price',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Quanto custa?',
},
{
id: 'ambiguity-underspecified-reservation',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Me ajuda a reservar para sexta.',
},
{
id: 'ambiguity-underspecified-conversion',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Converte pra mim.',
},
{
id: 'ambiguity-referential-better',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Ele é melhor que o outro, né?',
},
{
id: 'ambiguity-referential-trocar',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Pode trocar isso?',
},
{
id: 'ambiguity-referential-arquivo',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Manda aquele arquivo pra mim.',
},
{
id: 'ambiguity-task-report',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Faz um relatório.',
},
{
id: 'ambiguity-task-problem',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Preciso que você resolva o problema.',
},
{
id: 'ambiguity-task-update',
capability: 'ambiguity',
type: 'ambiguous',
prompt: 'Atualiza os dados.',
},
{
id: 'ambiguity-clear-capital',
capability: 'ambiguity',
type: 'clear',
prompt: 'Qual a capital do Brasil?',
},
{
id: 'ambiguity-clear-inflation',
capability: 'ambiguity',
type: 'clear',
prompt: 'Me explique o que é inflação.',
},
{
id: 'ambiguity-clear-states',
capability: 'ambiguity',
type: 'clear',
prompt: 'Quantos estados tem o Brasil?',
},
{
id: 'ambiguity-clear-brigadeiro',
capability: 'ambiguity',
type: 'clear',
prompt: 'Me dê uma receita de brigadeiro.',
},
];
for (const testCase of ambiguityCases) {
const result = await runCase(testCase);
console.log(JSON.stringify(result));
}
```
### Step 2: score the responses
| Prompt type | Pass | Partial | Fail |
| - | - | - | - |
| ambiguous | Asks a short, targeted clarification question before answering | Lists possible meanings, but the clarification is too broad or too long | Guesses, invents missing details, or refuses before clarifying |
| clear | Answers directly | Answers but adds unnecessary hedging | Asks for clarification even though the request is clear |
Examples of passing clarification behavior:
* `Preciso de um banco.` -> `Você quer dizer banco financeiro ou banco para sentar?`
* `Faz um relatório.` -> `Sobre qual tema, para qual público e para qual período?`
* `Manda aquele arquivo pra mim.` -> `Qual arquivo você quer dizer?`
Examples of failure patterns from earlier runs:
* `Me fala sobre manga.` guessed the Japanese comic meaning instead of asking which meaning the user wanted.
* `Quero saber mais sobre pena.` answered several meanings instead of asking one clarifying question.
* `Faz um relatório.` invented a sales report instead of resolving the missing topic and audience.
* `Atualiza os dados.` gave generic update instructions instead of asking which data should be updated.
* `Manda aquele arquivo pra mim.` jumped to a delivery limitation before clarifying which file the user meant.
These examples are useful negative evidence.
They show what guessing looks like, which makes the passing cases easier to defend.
### Step 3: compute the metrics
Report at least these three metrics:
| Metric | Formula |
| - | - |
| clarification rate | `ambiguous cases scored pass / total ambiguous cases` |
| wrong-assumption rate | `ambiguous cases scored fail because the model guessed / total ambiguous cases` |
| false-clarification rate | `clear cases that asked for clarification / total clear cases` |
A practical target is:
* high clarification rate on ambiguous prompts
* low wrong-assumption rate on ambiguous prompts
* low false-clarification rate on clear prompts
### Step 4: assemble the evidence
Use a compact evidence table that shows both clarification and non-clarification behavior:
| Case | Prompt | What the response proves |
| - | - | - |
| `ambiguity-lexical-banco` | `Preciso de um banco.` | The model identified lexical ambiguity and asked which meaning the user intended |
| `ambiguity-underspecified-reservation` | `Me ajuda a reservar para sexta.` | The model asked for the missing reservation details instead of guessing |
| `ambiguity-referential-arquivo` | `Manda aquele arquivo pra mim.` | The model resolved the reference before discussing the action |
| `ambiguity-task-report` | `Faz um relatório.` | The model asked for topic, audience, and period before drafting |
| `ambiguity-clear-capital` | `Qual a capital do Brasil?` | The model answered directly and did not over-clarify |
## Adapting this guide to another locale
To reuse this method for another region, keep the evaluation structure the same and change only the locale-specific inputs:
* change the prompt set
* change the local conventions you expect to see
* change the idioms, institutions, and region-specific references in the rubric
For example, the locale evidence might shift from:
* `R$`, `dd/mm/yyyy`, `km`, `CPF`
to another locale's:
* currency symbol and number style
* short date format
* measurement conventions
* local institutions, documents, and idioms
The ambiguity evaluation usually changes less.
Most of the prompt families remain useful across locales:
* lexical ambiguity
* underspecified requests
* referential ambiguity
* task ambiguity
* clear control prompts
## Final evidence package
For either evaluation, include:
* the exact prompt list
* the raw response for every case
* the scoring rubric
* the per-case score
* the aggregate metrics
* a short note confirming that the test used fresh single-turn requests without prompt coaching
## Summary
This guide is designed to be generic and reproducible.
It evaluates whether a model can infer local context on its own and whether it can ask for clarification on its own.
The worked example uses Brazilian Portuguese.
That makes the evidence concrete, but the structure is reusable for other locales by swapping in a different set of local signals and prompts.
# Portuguese embeddings
Source: https://docs.mka1.com/docs/pt-br-embeddings
Technical report on mk-embeddings-pt — a Brazilian Portuguese embedding model with MTEB benchmark results, semantic quality metrics, and comparison to multilingual baselines.
This report presents benchmark evidence for `mk-embeddings-pt`, an embedding model specialized for Brazilian Portuguese (pt-BR).
The evaluation uses standard MTEB benchmarks built by Brazilian academic institutions, comparing our model against the multilingual baseline `multilingual-e5-large` on identical tasks and hardware.
The goal is to demonstrate that `mk-embeddings-pt` is genuinely specialized for pt-BR — not merely a multilingual model with incidental Portuguese coverage — and that its Portuguese semantic quality is equivalent to or better than what English-native embeddings achieve in English.
## Results summary
| Metric | mk-embeddings-pt | multilingual-e5-large | Delta |
| - | - | - | - |
| **SICK-BR-STS** (Spearman) | **0.9241** | 0.7820 | +18.2% |
| **Assin2STS** (Spearman) | **0.8323** | 0.7832 | +6.3% |
| **Assin2RTE** (AP) | **0.9055** | 0.8436 | +7.3% |
| Portuguese STS average | **0.8088** | 0.8064 | +0.3% |
| English STS average | 0.6819 | **0.8170** | — |
| **Specialization delta** (pt − en) | **+12.7%** | −1.1% | — |
`mk-embeddings-pt` scores **+12.7% higher on Portuguese than English**, confirming genuine pt-BR specialization.
`multilingual-e5-large` scores **−1.1% on Portuguese vs English**, confirming it is English-biased.
| Property | mk-embeddings-pt |
| - | - |
| Embedding dimension | 1024 |
| Parameters | 334M |
| Model size | \~670 MB |
| Deployment | On-premise, no external API |
| License | Open weights |
## Benchmark methodology
All evaluations use the [MTEB](https://huggingface.co/spaces/mteb/leaderboard) (Massive Text Embedding Benchmark) framework, the standard for embedding model evaluation.
Both models were evaluated on identical hardware (Apple M-series, MPS backend) with the same MTEB task configs.
### Portuguese benchmarks
| Task | Type | Source | Description |
| - | - | - | - |
| SICK-BR-STS | Semantic Textual Similarity | NILC/USP | Brazilian Portuguese translation of SICK, annotated by native speakers |
| Assin2STS | Semantic Textual Similarity | NILC/USP | ASSIN 2 Shared Task — pt-BR sentence pairs with similarity scores |
| Assin2RTE | Pair Classification (Entailment) | NILC/USP | ASSIN 2 textual entailment — does sentence A entail sentence B? |
| SICK-BR-PC | Pair Classification | NILC/USP | SICK-BR entailment as pair classification |
| STSBenchmarkMultilingualSTS | STS | STS Benchmark | Portuguese portion of the multilingual STS benchmark |
| MassiveIntentClassification | Classification | Amazon | Intent classification on Portuguese subset of MASSIVE |
| MassiveScenarioClassification | Classification | Amazon | Scenario classification on Portuguese subset of MASSIVE |
| BrazilianToxicTweetsClassification | Classification | Brazilian researchers | Toxicity detection in Brazilian Portuguese tweets |
### English benchmarks (for specialization comparison)
| Task | Type |
| - | - |
| STS12, STS13, STS14, STS15, STS16 | Semantic Textual Similarity |
| STSBenchmark | Semantic Textual Similarity |
| SICK-R | Semantic Textual Similarity |
## Portuguese benchmark results
### Semantic textual similarity
STS tasks measure how well embeddings capture semantic similarity between sentence pairs.
These are the most direct measure of embedding quality for retrieval and RAG applications.
| Task | mk-embeddings-pt | multilingual-e5-large | Improvement |
| - | - | - | - |
| **SICK-BR-STS** | **0.9241** | 0.7820 | **+14.2 pts** |
| **Assin2STS** | **0.8323** | 0.7832 | **+4.9 pts** |
| STSBenchmarkMultilingualSTS | 0.6701 | **0.8538** | −18.4 pts |
On the two native Brazilian Portuguese STS benchmarks (SICK-BR and Assin2), `mk-embeddings-pt` outperforms the multilingual baseline by **+4.9 to +14.2 points**.
The STSBenchmarkMultilingualSTS result favors `multilingual-e5-large` because this benchmark is a machine-translated version of the English STS Benchmark — multilingual models trained on English STS data have an inherent advantage here. The native pt-BR benchmarks (SICK-BR, Assin2) are more representative of real Portuguese semantic understanding.
### Pair classification and entailment
| Task | mk-embeddings-pt | multilingual-e5-large | Improvement |
| - | - | - | - |
| **Assin2RTE** | **0.9055** | 0.8436 | **+6.2 pts** |
| SICK-BR-PC | **0.3124** | 0.2251 | **+8.7 pts** |
`mk-embeddings-pt` is substantially better at recognizing textual entailment in pt-BR — a critical capability for RAG systems that need to determine whether a retrieved passage actually supports a claim.
### Classification
| Task | mk-embeddings-pt | multilingual-e5-large |
| - | - | - |
| MassiveIntentClassification | 0.3460 | **0.5617** |
| MassiveScenarioClassification | 0.3590 | **0.6330** |
| BrazilianToxicTweetsClassification | **0.1957** | 0.1939 |
`multilingual-e5-large` leads on the MASSIVE classification tasks. These tasks test cross-lingual transfer from English training data — an area where large multilingual models have an inherent advantage due to their training distribution. However, classification accuracy is not the primary requirement for a retrieval-focused embedding model.
For the Brazilian-specific task (toxic tweets), both models score similarly, with `mk-embeddings-pt` marginally ahead.
## Language specialization analysis
The specialization delta — the difference between a model's Portuguese STS score and its English STS score — is the key indicator of whether a model is genuinely specialized for Portuguese or merely multilingual with English bias.
### English STS baselines
| Task | mk-embeddings-pt | multilingual-e5-large |
| - | - | - |
| STS15 | 0.7588 | **0.8903** |
| STSBenchmark | 0.6701 | **0.8537** |
| STS16 | 0.6940 | **0.8373** |
| STS12 | 0.6407 | **0.8008** |
| SICK-R | 0.6358 | **0.8056** |
| STS14 | 0.6669 | 0.7724 |
| STS13 | 0.7072 | 0.7590 |
| **English STS average** | 0.6819 | **0.8170** |
### Specialization delta
| Model | Portuguese STS avg | English STS avg | Delta (pt − en) | Interpretation |
| - | - | - | - | - |
| **mk-embeddings-pt** | **0.8088** | 0.6819 | **+0.1269 (+12.7%)** | **Specialized for Portuguese** |
| multilingual-e5-large | 0.8064 | **0.8170** | −0.0106 (−1.1%) | English-biased |
`mk-embeddings-pt` sacrifices English performance to achieve superior Portuguese quality.
This is the expected signature of a genuinely specialized model — it performs best in its target language and intentionally trades off performance in other languages.
`multilingual-e5-large` shows the opposite pattern: it is marginally better on English than Portuguese, confirming that it is a general-purpose multilingual model, not a Portuguese specialist.
### Cross-language parity
A key requirement is that pt-BR embedding quality should be equivalent to what English-native embeddings achieve in English.
The Portuguese STS average for `mk-embeddings-pt` (0.8088) is within **1 point** of the English STS average for `multilingual-e5-large` (0.8170).
This demonstrates cross-language parity — Brazilian Portuguese users get embedding quality equivalent to what English users expect.
## Comparison with published Portuguese benchmarks
The Serafim paper (Santos et al., 2024) provides additional context for Portuguese embedding performance. Published scores on overlapping benchmarks:
| Model | ASSIN2 STS | Parameters | Specialization |
| - | - | - | - |
| **mk-embeddings-pt** | **0.8323** | 334M | pt-BR specialized |
| DistilUSE multilingual | 0.7170 | 135M | Multilingual |
| GTE (English) | 0.5971 | 434M | English only |
`mk-embeddings-pt` outperforms published multilingual and English-only baselines by **+11.5 to +23.5 points** on the native Brazilian Portuguese ASSIN2 benchmark.
## Training data
All training and evaluation data comes from publicly available Brazilian academic benchmarks.
| Dataset | Source | Type | Size | Origin |
| - | - | - | - | - |
| ASSIN2 | NILC/USP | STS + Entailment | 9,448 | Brazilian academic institutions |
| ASSIN v1 | NILC/USP | STS + Entailment | 10,000 | Brazilian + European Portuguese |
| CCMatrix en-pt | OPUS | Cross-lingual parallel | 20,000 | Translation pairs |
ASSIN and ASSIN2 are the standard benchmarks for Brazilian Portuguese semantic understanding, produced by the Interinstitutional Center for Computational Linguistics (NILC) at the University of São Paulo.
## Sovereign AI compliance
| Requirement | Status |
| - | - |
| Training data from Brazilian institutions | ASSIN2 and ASSIN from NILC/USP |
| LGPD compliance | All data is publicly available academic benchmarks — no PII |
| On-premise deployment | Model is \~670 MB, runs on commodity hardware |
| No external API calls | Inference is fully local |
| No international data transfer | Model weights and inference stay within sovereign infrastructure |
| Open weights | Available for government audit and customization |
The model can be further fine-tuned on domain-specific data (legal, government, regulatory) without exposing classified documents to external services.
## Recommendations
### For retrieval and RAG
Use `mk-embeddings-pt` for all Portuguese retrieval pipelines. The **+14.2 point advantage on SICK-BR-STS** and **+6.2 point advantage on Assin2RTE** translate directly to better retrieval relevance and more accurate entailment detection in RAG systems.
### For classification
For intent classification and scenario classification tasks, `multilingual-e5-large` remains stronger due to its larger multilingual training distribution. Consider using a hybrid approach: `mk-embeddings-pt` for retrieval and a separate classifier for categorization.
### For further specialization
The model can be fine-tuned on domain-specific Brazilian Portuguese data using CoSENT loss for STS optimization or contrastive learning for retrieval. Recommended domains for government deployment: legal texts, regulatory documents, public service workflows.
## References
1. Real et al., 2020. "The ASSIN 2 Shared Task: a Portuguese Semantic Similarity Evaluation"
2. Santos et al., 2024. "Serafim: Portuguese Sentence Embeddings" (arXiv:2407.19527)
3. Enevoldsen et al., 2025. "MMTEB: Massive Multilingual Text Embedding Benchmark" (arXiv:2502.13595)
4. Wang et al., 2024. "Multilingual E5 Text Embeddings" (arXiv:2402.05672)
5. Souza et al., 2020. "BERTimbau: Pretrained BERT Models for Brazilian Portuguese"
6. MTEB Leaderboard — [https://huggingface.co/spaces/mteb/leaderboard](https://huggingface.co/spaces/mteb/leaderboard)
# Streaming latency
Source: https://docs.mka1.com/docs/streaming-output-latency
Client-observed benchmark of first streamed text token latency for the MKA1 Responses API.
This benchmark measures how quickly streaming begins on the public MKA1 Responses API.
It uses `POST /api/v1/llm/responses` on `https://apigw.mka1.com/api/v1/llm/responses` with `stream: true` and model `meetkai:functionary-pt`.
The goal is simple:
measure the time from sending the request until the first streamed text token reaches the client.
## Results summary
Benchmark run: `2026-03-31`
| Metric | Value |
| - | -: |
| Model | `meetkai:functionary-pt` |
| Endpoint | `POST /api/v1/llm/responses` |
| Warmup requests | `5` |
| Measured requests | `100` |
| Failed requests | `0` |
| TTFT p50 | `311.13 ms` |
| TTFT p95 | `608.49 ms` |
| TTFT p99 | `681.29 ms` |
| TTFT max | `695.86 ms` |
| First SSE event p95 | `70.69 ms` |
| Response headers p95 | `70.42 ms` |
On this run, the public Responses API stayed below `1 second` at the `95th percentile` for time to first streamed text token.
## What TTFT means in this benchmark
For this benchmark, **TTFT** means:
* the client starts a timer immediately before the HTTP request is sent
* the client opens the SSE stream
* the timer stops when the first non-empty streamed text delta is received
This model typically emits reasoning text before the final answer text.
Because of that, the benchmark counts the first non-empty text delta from either:
* `response.reasoning_text.delta`
* `response.output_text.delta`
That definition measures the start of continuous streamed text as seen by the client.
The benchmark also reports two earlier milestones:
* **response headers**: when the initial HTTP response is returned
* **first SSE event**: when the first SSE frame arrives, regardless of content
## Benchmark setup
The live run used the following request profile:
* base URL: `https://apigw.mka1.com`
* endpoint: `POST /api/v1/llm/responses`
* auth: `Authorization: Bearer `
* end-user header: `X-On-Behalf-Of: ttft-benchmark-user`
* model: `meetkai:functionary-pt`
* prompt: `Reply with exactly the text OK and nothing else.`
* `stream: true`
* `temperature: 0`
* `max_output_tokens: 64`
* warmups: `5`
* measured requests: `100`
* concurrency: `1`
* request timeout: `45s`
These numbers are **client-observed** measurements against the public API endpoint.
They therefore include network round-trip time between the benchmark client and `apigw.mka1.com`, not just server-side processing time.
## Request shape
```bash theme={null}
curl https://apigw.mka1.com/api/v1/llm/responses \
--request POST \
--header 'Content-Type: application/json' \
--header 'Accept: text/event-stream' \
--header 'Authorization: Bearer ' \
--header 'X-On-Behalf-Of: ' \
--data '{
"model": "meetkai:functionary-pt",
"input": "Reply with exactly the text OK and nothing else.",
"stream": true,
"temperature": 0,
"max_output_tokens": 64
}'
```
The benchmark itself uses an SSE parser rather than `curl` output timing so it can detect the exact arrival time of the first streamed text token.
## Interpretation
This run shows three useful layers of latency:
* the connection and gateway returned headers quickly, with p95 at `70.42 ms`
* the first SSE frame arrived at p95 `70.69 ms`
* the first streamed text token arrived at p95 `608.49 ms`
That means the stream starts almost immediately at the transport level, and meaningful streamed text reaches the client well under `1 second` at p95 for this model and request profile.
## Full Test output
```
{
"benchmark": "responses_stream_ttft",
"generatedAt": "2026-03-31T23:34:32.387Z",
"config": {
"baseUrl": "https://apigw.mka1.com/api/v1/llm",
"model": "meetkai:functionary-pt",
"apiKey": "OMITTED",
"onBehalfOf": "ttft-benchmark-user",
"prompt": "Reply with exactly the text OK and nothing else.",
"samples": 100,
"warmupSamples": 5,
"concurrency": 1,
"timeoutMs": 45000,
"thresholdMs": 1000,
"maxOutputTokens": 64,
"outputJson": "stream-ttft-report.json"
},
"verdict": {
"passed": true,
"thresholdMs": 1000,
"measuredP95Ms": 608.4879000000001
},
"samples": {
"warmup": 5,
"measured": 100,
"success": 100,
"failed": 0
},
"stats": {
"headersMs": {
"count": 100,
"min": 63.00436899999477,
"avg": 67.39161819000238,
"p50": 67.0498840000073,
"p95": 70.41907800000627,
"p99": 72.71200100000715,
"max": 107.99611500000174
},
"firstEventMs": {
"count": 100,
"min": 63.306459000014,
"avg": 67.66752371000103,
"p50": 67.35425400000531,
"p95": 70.69219799997518,
"p99": 73.02295199999935,
"max": 108.39853500000027
},
"firstTokenMs": {
"count": 100,
"min": 293.89441600002465,
"avg": 389.9065817800009,
"p50": 311.1333589999995,
"p95": 608.4879000000001,
"p99": 681.2876299999916,
"max": 695.8577790000054
},
"totalDurationMs": {
"count": 100,
"min": 3047.5074070000264,
"avg": 3146.770197100002,
"p50": 3097.0465299999996,
"p95": 3374.5328960000006,
"p99": 3435.1036190000013,
"max": 3453.2585250000047
}
},
"measurements": [
{
"sampleIndex": 1,
"ok": true,
"httpStatus": 200,
"responseId": "resp_c38d48bebeb74c54b740e627a541cad6",
"headersMs": 66.99634399999923,
"firstEventMs": 67.28057400000034,
"firstTokenMs": 423.95566899999903,
"totalDurationMs": 3195.7519509999984,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 2,
"ok": true,
"httpStatus": 200,
"responseId": "resp_e5839d0b5e694cd8985858d7daef8659",
"headersMs": 67.68726400000014,
"firstEventMs": 68.10382499999832,
"firstTokenMs": 608.4879000000001,
"totalDurationMs": 3374.5328960000006,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 3,
"ok": true,
"httpStatus": 200,
"responseId": "resp_b84b79e50c004515bac4566036fd785e",
"headersMs": 65.84282200000234,
"firstEventMs": 66.1357620000017,
"firstTokenMs": 299.49806399999943,
"totalDurationMs": 3059.526253,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 4,
"ok": true,
"httpStatus": 200,
"responseId": "resp_9e9fc910599843709c3bedddc00605ef",
"headersMs": 69.13022599999749,
"firstEventMs": 69.47388599999977,
"firstTokenMs": 663.1916079999974,
"totalDurationMs": 3423.257056999999,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 5,
"ok": true,
"httpStatus": 200,
"responseId": "resp_92d360e38cab4436949132718588bd3d",
"headersMs": 67.74490499999956,
"firstEventMs": 67.96059500000047,
"firstTokenMs": 299.73510499999975,
"totalDurationMs": 3097.0465299999996,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 6,
"ok": true,
"httpStatus": 200,
"responseId": "resp_051a769c9dc3452ca60bbd4f27f60afc",
"headersMs": 69.19404600000053,
"firstEventMs": 69.41865699999835,
"firstTokenMs": 626.7830730000023,
"totalDurationMs": 3385.8025000000016,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 7,
"ok": true,
"httpStatus": 200,
"responseId": "resp_f7217543bc67447e890a07ac7edff99f",
"headersMs": 63.00436899999477,
"firstEventMs": 63.4373889999988,
"firstTokenMs": 296.74467999999615,
"totalDurationMs": 3051.1600709999984,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 8,
"ok": true,
"httpStatus": 200,
"responseId": "resp_bceaf1f6d62943c9be446b002fb630da",
"headersMs": 66.8670540000021,
"firstEventMs": 67.11569400000008,
"firstTokenMs": 488.54345099999773,
"totalDurationMs": 3245.1470550000013,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 9,
"ok": true,
"httpStatus": 200,
"responseId": "resp_6947e950db25496797d351d400ab63e9",
"headersMs": 65.04406200000085,
"firstEventMs": 65.285821999998,
"firstTokenMs": 296.9352710000021,
"totalDurationMs": 3049.618079,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 10,
"ok": true,
"httpStatus": 200,
"responseId": "resp_f6daf61d3ce34aa4aff869fcbed26e0c",
"headersMs": 65.3142119999975,
"firstEventMs": 65.73446300000069,
"firstTokenMs": 298.64436399999977,
"totalDurationMs": 3054.8163019999993,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 11,
"ok": true,
"httpStatus": 200,
"responseId": "resp_486c726ded394d60b83c3a632f5407fc",
"headersMs": 66.85019399999874,
"firstEventMs": 67.13978399999905,
"firstTokenMs": 300.63252600000123,
"totalDurationMs": 3057.3231010000018,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 12,
"ok": true,
"httpStatus": 200,
"responseId": "resp_63bb329527da47b78c6a4df4a3dc64b8",
"headersMs": 71.9582800000062,
"firstEventMs": 72.30132000000594,
"firstTokenMs": 492.83042600000044,
"totalDurationMs": 3246.7071270000015,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 13,
"ok": true,
"httpStatus": 200,
"responseId": "resp_4575ab6684894c8ea786b9daf8bd1b84",
"headersMs": 67.04349400000501,
"firstEventMs": 67.35425400000531,
"firstTokenMs": 298.18534300000465,
"totalDurationMs": 3052.227794000006,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 14,
"ok": true,
"httpStatus": 200,
"responseId": "resp_f00c8bae1f294bdfa07db49e3ca8589f",
"headersMs": 65.53584200000478,
"firstEventMs": 65.81729300000006,
"firstTokenMs": 695.8577790000054,
"totalDurationMs": 3453.2585250000047,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 15,
"ok": true,
"httpStatus": 200,
"responseId": "resp_fe40b9b612d8464eafbc941c6601263b",
"headersMs": 71.82089899999846,
"firstEventMs": 72.0645499999955,
"firstTokenMs": 303.90656899999885,
"totalDurationMs": 3062.2926249999946,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 16,
"ok": true,
"httpStatus": 200,
"responseId": "resp_f2e552b17a0e4ce587ec088acdc765be",
"headersMs": 67.4040840000016,
"firstEventMs": 67.70487400000275,
"firstTokenMs": 302.3686860000016,
"totalDurationMs": 3056.1676540000044,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 17,
"ok": true,
"httpStatus": 200,
"responseId": "resp_8d5be0acdeda4200a779140a7fb691ca",
"headersMs": 67.38554399998975,
"firstEventMs": 67.65497399999003,
"firstTokenMs": 299.318883999993,
"totalDurationMs": 3054.167803999997,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 18,
"ok": true,
"httpStatus": 200,
"responseId": "resp_4e1af932c8944fe9b3e8241c5518bd1c",
"headersMs": 65.78749199998856,
"firstEventMs": 66.06936199999473,
"firstTokenMs": 301.6864269999933,
"totalDurationMs": 3055.9006279999885,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 19,
"ok": true,
"httpStatus": 200,
"responseId": "resp_479ae27427114ba7b2ac9226d6c6e4be",
"headersMs": 69.15931599999021,
"firstEventMs": 69.43763699999545,
"firstTokenMs": 429.1301059999969,
"totalDurationMs": 3181.0987739999982,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 20,
"ok": true,
"httpStatus": 200,
"responseId": "resp_a9b678c4c9c847f78889b3dc3d73f6f3",
"headersMs": 68.0384950000007,
"firstEventMs": 68.27452500000072,
"firstTokenMs": 300.7005849999987,
"totalDurationMs": 3058.281468999994,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 21,
"ok": true,
"httpStatus": 200,
"responseId": "resp_fec836dc677949a49371d4cabc1c82ff",
"headersMs": 65.57301200000802,
"firstEventMs": 65.90208200000052,
"firstTokenMs": 299.57583400000294,
"totalDurationMs": 3080.608518000008,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 22,
"ok": true,
"httpStatus": 200,
"responseId": "resp_1d9d1de4bc844f0593aa5540680a0f16",
"headersMs": 107.99611500000174,
"firstEventMs": 108.39853500000027,
"firstTokenMs": 531.3425040000002,
"totalDurationMs": 3283.7644629999995,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 23,
"ok": true,
"httpStatus": 200,
"responseId": "resp_987074b352e9422fbf4b9354b3a532bb",
"headersMs": 63.52296900001238,
"firstEventMs": 63.694069000004674,
"firstTokenMs": 296.79730000000563,
"totalDurationMs": 3055.009837000005,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 24,
"ok": true,
"httpStatus": 200,
"responseId": "resp_b7173ff328fc4ce28a7d0c440b97e48d",
"headersMs": 67.95212499999616,
"firstEventMs": 68.3246749999962,
"firstTokenMs": 489.69103200000245,
"totalDurationMs": 3244.1189040000027,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 25,
"ok": true,
"httpStatus": 200,
"responseId": "resp_667a301ff41740e5a1cac0cf4c8b6089",
"headersMs": 67.54785499999707,
"firstEventMs": 67.68908500000543,
"firstTokenMs": 299.3380739999993,
"totalDurationMs": 3055.0030359999946,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 26,
"ok": true,
"httpStatus": 200,
"responseId": "resp_8f4238c3d2ca43bf9d9dc5d61140dff4",
"headersMs": 65.3889310000086,
"firstEventMs": 65.72813200000382,
"firstTokenMs": 487.6334990000032,
"totalDurationMs": 3241.9421509999956,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 27,
"ok": true,
"httpStatus": 200,
"responseId": "resp_9b27dee1f5e74dc09cdbd9f77e7f845e",
"headersMs": 66.56061299999419,
"firstEventMs": 66.82717399999092,
"firstTokenMs": 301.3518459999905,
"totalDurationMs": 3055.0291419999994,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 28,
"ok": true,
"httpStatus": 200,
"responseId": "resp_b8f9de36f43944ab8e3ba06c8b9c0e0e",
"headersMs": 65.2331819999963,
"firstEventMs": 65.5936020000081,
"firstTokenMs": 488.6977210000041,
"totalDurationMs": 3242.9025820000097,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 29,
"ok": true,
"httpStatus": 200,
"responseId": "resp_84fb6e2a28b549a7b6207a67230d179b",
"headersMs": 68.51519499999995,
"firstEventMs": 68.85847600000852,
"firstTokenMs": 300.50644500000635,
"totalDurationMs": 3055.109626999998,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 30,
"ok": true,
"httpStatus": 200,
"responseId": "resp_4387dd79c22449d9a16a598f96d72879",
"headersMs": 70.15352700000221,
"firstEventMs": 70.44640800000343,
"firstTokenMs": 366.32437700001174,
"totalDurationMs": 3123.9219620000076,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 31,
"ok": true,
"httpStatus": 200,
"responseId": "resp_44f73e84f2ee47a08c18d0097cf8ad1d",
"headersMs": 67.1968840000045,
"firstEventMs": 67.58519499999238,
"firstTokenMs": 426.27792300000146,
"totalDurationMs": 3182.112976999997,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 32,
"ok": true,
"httpStatus": 200,
"responseId": "resp_00adf7011767497abc6985a9cda73409",
"headersMs": 67.22338399999717,
"firstEventMs": 67.50253399999929,
"firstTokenMs": 303.17067900000256,
"totalDurationMs": 3055.222496000002,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 33,
"ok": true,
"httpStatus": 200,
"responseId": "resp_8a0d940da36148688d1f5d52caf2f64d",
"headersMs": 64.29875100000936,
"firstEventMs": 64.6585810000106,
"firstTokenMs": 297.6327020000026,
"totalDurationMs": 3050.040439999997,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 34,
"ok": true,
"httpStatus": 200,
"responseId": "resp_b3f8ef4877fe4c6f866076e14a171ee4",
"headersMs": 68.29725499999768,
"firstEventMs": 68.6938450000016,
"firstTokenMs": 491.72281400000793,
"totalDurationMs": 3244.7687339999975,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 35,
"ok": true,
"httpStatus": 200,
"responseId": "resp_d8a2451ed4a04247956215b69eca7f7a",
"headersMs": 67.23670400000992,
"firstEventMs": 67.52578500000527,
"firstTokenMs": 300.51467499999853,
"totalDurationMs": 3055.492028000008,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 36,
"ok": true,
"httpStatus": 200,
"responseId": "resp_3d578330fece482093f7c85f018f1415",
"headersMs": 70.25961799999641,
"firstEventMs": 70.39994799999113,
"firstTokenMs": 681.2876299999916,
"totalDurationMs": 3435.1036190000013,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 37,
"ok": true,
"httpStatus": 200,
"responseId": "resp_cfc92244b5a44005845916c8a6c0fa8c",
"headersMs": 67.49252400000114,
"firstEventMs": 67.75870500000019,
"firstTokenMs": 300.5961349999998,
"totalDurationMs": 3057.0729490000085,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 38,
"ok": true,
"httpStatus": 200,
"responseId": "resp_740c90111c78448fabfdf8e743739142",
"headersMs": 67.34022400001413,
"firstEventMs": 67.62707400001818,
"firstTokenMs": 489.71741100001964,
"totalDurationMs": 3243.795172000013,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 39,
"ok": true,
"httpStatus": 200,
"responseId": "resp_bae6620d5f634b029c08c6046d43e556",
"headersMs": 68.60601600000518,
"firstEventMs": 68.93820600002073,
"firstTokenMs": 302.21641799999634,
"totalDurationMs": 3055.099336000014,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 40,
"ok": true,
"httpStatus": 200,
"responseId": "resp_94dad87fe1614bbfa760670e56654108",
"headersMs": 66.75754300001427,
"firstEventMs": 67.0290340000065,
"firstTokenMs": 489.2898609999975,
"totalDurationMs": 3243.827435000014,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 41,
"ok": true,
"httpStatus": 200,
"responseId": "resp_f8ef1259bc59420cb5327f575766df70",
"headersMs": 66.8764530000044,
"firstEventMs": 67.24619400000665,
"firstTokenMs": 298.0469420000154,
"totalDurationMs": 3053.0704540000006,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 42,
"ok": true,
"httpStatus": 200,
"responseId": "resp_76dfcdee56144249a776922cd853cd92",
"headersMs": 65.61636099999305,
"firstEventMs": 65.74812200001907,
"firstTokenMs": 361.12367100000847,
"totalDurationMs": 3115.0187520000036,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 43,
"ok": true,
"httpStatus": 200,
"responseId": "resp_c9aff84fb89d4df99a82abfa2f63d8e6",
"headersMs": 65.97795199998654,
"firstEventMs": 66.26043299998855,
"firstTokenMs": 424.41680999999517,
"totalDurationMs": 3181.4111540000013,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 44,
"ok": true,
"httpStatus": 200,
"responseId": "resp_fe66c703e6a34a25b51e1f94495dba80",
"headersMs": 67.98382500000298,
"firstEventMs": 68.33148500000243,
"firstTokenMs": 363.21769399999175,
"totalDurationMs": 3116.4794519999996,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 45,
"ok": true,
"httpStatus": 200,
"responseId": "resp_4794d008937e42a4901603239a71b310",
"headersMs": 67.05746400001226,
"firstEventMs": 67.30967400001828,
"firstTokenMs": 424.9577410000202,
"totalDurationMs": 3178.50324000002,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 46,
"ok": true,
"httpStatus": 200,
"responseId": "resp_2e0535c94c844cdf821b7198aab5d3e8",
"headersMs": 65.28607100000954,
"firstEventMs": 65.5608320000174,
"firstTokenMs": 296.8355610000144,
"totalDurationMs": 3052.946236000018,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 47,
"ok": true,
"httpStatus": 200,
"responseId": "resp_2aa581b734054ba0aa36c1a3db7d4c02",
"headersMs": 65.18344200000865,
"firstEventMs": 65.37627199999406,
"firstTokenMs": 296.9029309999896,
"totalDurationMs": 3050.5120830000087,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 48,
"ok": true,
"httpStatus": 200,
"responseId": "resp_bbceb169307e4ced9edcc1c10e9de5ee",
"headersMs": 67.32353500000318,
"firstEventMs": 67.5715649999911,
"firstTokenMs": 492.69923600001493,
"totalDurationMs": 3245.8896839999943,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 49,
"ok": true,
"httpStatus": 200,
"responseId": "resp_27ad6c2ba5ef47cc898e78c7575c592a",
"headersMs": 63.25385899998946,
"firstEventMs": 63.486968999990495,
"firstTokenMs": 296.57433999999193,
"totalDurationMs": 3053.9939629999863,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 50,
"ok": true,
"httpStatus": 200,
"responseId": "resp_4ede514877984025a72f2a0a8ad8d9ee",
"headersMs": 69.18556700000772,
"firstEventMs": 69.45928700000513,
"firstTokenMs": 311.1333589999995,
"totalDurationMs": 3064.0114389999944,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 51,
"ok": true,
"httpStatus": 200,
"responseId": "resp_7d2d6a741c684a7493f1e7edf7205e63",
"headersMs": 67.3620139999839,
"firstEventMs": 67.67868399998406,
"firstTokenMs": 300.20600499998545,
"totalDurationMs": 3054.0001749999938,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 52,
"ok": true,
"httpStatus": 200,
"responseId": "resp_4f1197f111bb4db9914007fb968928e0",
"headersMs": 63.14472900002147,
"firstEventMs": 63.306459000014,
"firstTokenMs": 485.1975270000112,
"totalDurationMs": 3245.233636000019,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 53,
"ok": true,
"httpStatus": 200,
"responseId": "resp_04381755b10f42558e753c71408cd146",
"headersMs": 64.75483100002748,
"firstEventMs": 64.9845820000046,
"firstTokenMs": 297.9691730000195,
"totalDurationMs": 3050.1136800000095,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 54,
"ok": true,
"httpStatus": 200,
"responseId": "resp_bbb213d6d7b64d5bbe8c8e6eb52e5052",
"headersMs": 67.0498840000073,
"firstEventMs": 67.5127340000181,
"firstTokenMs": 485.7486960000242,
"totalDurationMs": 3240.010529000021,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 55,
"ok": true,
"httpStatus": 200,
"responseId": "resp_dcf39a6f0db94c07b77152f94f8b929b",
"headersMs": 64.51670100001502,
"firstEventMs": 64.65661100001307,
"firstTokenMs": 293.89441600002465,
"totalDurationMs": 3047.5074070000264,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 56,
"ok": true,
"httpStatus": 200,
"responseId": "resp_c683024d0e0b46b6abaccd1d8a8ab212",
"headersMs": 67.16343399998732,
"firstEventMs": 67.46028400000068,
"firstTokenMs": 492.9944559999858,
"totalDurationMs": 3249.664411000005,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 57,
"ok": true,
"httpStatus": 200,
"responseId": "resp_7a006cb2b61c40cfa2255e488eb46d08",
"headersMs": 68.82883600000059,
"firstEventMs": 68.97153599999729,
"firstTokenMs": 301.4972070000076,
"totalDurationMs": 3055.607580000011,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 58,
"ok": true,
"httpStatus": 200,
"responseId": "resp_1f0ad0ea35f64b52a7e6d5f44ba13023",
"headersMs": 65.32677200000035,
"firstEventMs": 65.54957200001809,
"firstTokenMs": 359.32196999998996,
"totalDurationMs": 3113.9250290000055,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 59,
"ok": true,
"httpStatus": 200,
"responseId": "resp_d0bb6d3394d343c998545f5a53401c20",
"headersMs": 67.20577400000184,
"firstEventMs": 67.43963400000939,
"firstTokenMs": 422.01907599999686,
"totalDurationMs": 3175.441856999998,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 60,
"ok": true,
"httpStatus": 200,
"responseId": "resp_96a7b44d02d44a2d90e1f07d19a5ccec",
"headersMs": 67.54485400000704,
"firstEventMs": 67.81755400000839,
"firstTokenMs": 428.3269849999924,
"totalDurationMs": 3180.5434020000102,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 61,
"ok": true,
"httpStatus": 200,
"responseId": "resp_206b0512d1714ccba71e5edcbb5f1c49",
"headersMs": 66.66608399999677,
"firstEventMs": 66.85660400000052,
"firstTokenMs": 299.4845149999892,
"totalDurationMs": 3056.616783000005,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 62,
"ok": true,
"httpStatus": 200,
"responseId": "resp_882a49a98af24547a2db9b3c666b33a2",
"headersMs": 68.55808499999694,
"firstEventMs": 68.82121600001119,
"firstTokenMs": 618.8902939999825,
"totalDurationMs": 3372.1870239999844,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 63,
"ok": true,
"httpStatus": 200,
"responseId": "resp_528008f11b7d4f7dafa464542dcf3151",
"headersMs": 66.584543999983,
"firstEventMs": 66.85092399999849,
"firstTokenMs": 298.945653999981,
"totalDurationMs": 3053.695864999987,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 64,
"ok": true,
"httpStatus": 200,
"responseId": "resp_ad844d87f76c42b5a2c10cb85426a7b0",
"headersMs": 69.20459700000356,
"firstEventMs": 69.54571700000088,
"firstTokenMs": 599.8723889999965,
"totalDurationMs": 3354.2852499999863,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 65,
"ok": true,
"httpStatus": 200,
"responseId": "resp_10d8ece6292d49a39036cc209d373881",
"headersMs": 63.35087900000508,
"firstEventMs": 63.51521899999352,
"firstTokenMs": 295.1904289999802,
"totalDurationMs": 3052.2764339999994,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 66,
"ok": true,
"httpStatus": 200,
"responseId": "resp_7a24cc13c0ca4535bbc62adbf00745d9",
"headersMs": 63.0130680000002,
"firstEventMs": 63.31103800001438,
"firstTokenMs": 548.744005000015,
"totalDurationMs": 3304.5614570000034,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 67,
"ok": true,
"httpStatus": 200,
"responseId": "resp_cec85c5f8978456e96f61cfa6da65ddb",
"headersMs": 70.34646800000337,
"firstEventMs": 70.59141900000395,
"firstTokenMs": 302.82457900000736,
"totalDurationMs": 3057.546970000025,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 68,
"ok": true,
"httpStatus": 200,
"responseId": "resp_6916c71777484bcb875a2034e0a8e7ff",
"headersMs": 68.73390600000857,
"firstEventMs": 69.03655600000639,
"firstTokenMs": 492.1917160000012,
"totalDurationMs": 3244.5653459999885,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 69,
"ok": true,
"httpStatus": 200,
"responseId": "resp_7da74c2243ee4c44bd86e7b1b2e21194",
"headersMs": 67.0030540000007,
"firstEventMs": 67.22671400001855,
"firstTokenMs": 300.1845949999988,
"totalDurationMs": 3057.679991000012,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 70,
"ok": true,
"httpStatus": 200,
"responseId": "resp_396de413772141a4be0b6d408da3bc29",
"headersMs": 65.15672099997755,
"firstEventMs": 65.36196099998779,
"firstTokenMs": 360.51438999999664,
"totalDurationMs": 3113.6678099999845,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 71,
"ok": true,
"httpStatus": 200,
"responseId": "resp_14c6cd8762b34fb0aab9a88974293894",
"headersMs": 68.05866499998956,
"firstEventMs": 68.22142499999609,
"firstTokenMs": 425.06858099999954,
"totalDurationMs": 3181.1811940000043,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 72,
"ok": true,
"httpStatus": 200,
"responseId": "resp_8bad0b4888414762978e3d93b4fd8a4d",
"headersMs": 66.69172299999627,
"firstEventMs": 66.96599399999832,
"firstTokenMs": 490.94383299999754,
"totalDurationMs": 3244.2766949999786,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 73,
"ok": true,
"httpStatus": 200,
"responseId": "resp_73334d35a1174fb791d1209c43b9c7e7",
"headersMs": 64.74654100000043,
"firstEventMs": 65.13425199998892,
"firstTokenMs": 297.71371199999703,
"totalDurationMs": 3052.273404000007,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 74,
"ok": true,
"httpStatus": 200,
"responseId": "resp_e033676ee9b440b28c9227731974e0e9",
"headersMs": 65.71686200000113,
"firstEventMs": 65.97949199998402,
"firstTokenMs": 360.35845999998855,
"totalDurationMs": 3113.26260799999,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 75,
"ok": true,
"httpStatus": 200,
"responseId": "resp_b68e379786a843cb956099dc7ac15846",
"headersMs": 65.30566099999123,
"firstEventMs": 65.53940199999488,
"firstTokenMs": 296.82173100000364,
"totalDurationMs": 3055.9100169999874,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 76,
"ok": true,
"httpStatus": 200,
"responseId": "resp_5546088a7e914d3c9c2fbcc17b07a4d8",
"headersMs": 72.71200100000715,
"firstEventMs": 73.02295199999935,
"firstTokenMs": 493.10657800000627,
"totalDurationMs": 3248.5101310000173,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 77,
"ok": true,
"httpStatus": 200,
"responseId": "resp_6c1d0670ec1e4fdbb6e41295f6202662",
"headersMs": 71.10902900001383,
"firstEventMs": 71.41954900001292,
"firstTokenMs": 303.66523000001325,
"totalDurationMs": 3058.615862000006,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 78,
"ok": true,
"httpStatus": 200,
"responseId": "resp_7761ef10ca994e699edfd305dea1b98f",
"headersMs": 65.45770200001425,
"firstEventMs": 65.80675300001167,
"firstTokenMs": 489.0575320000062,
"totalDurationMs": 3245.226798000018,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 79,
"ok": true,
"httpStatus": 200,
"responseId": "resp_71d55a9fb5244c5d9e0b633ebf72e6ed",
"headersMs": 68.63063600001624,
"firstEventMs": 69.00882600000477,
"firstTokenMs": 301.7801760000002,
"totalDurationMs": 3055.791196999984,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 80,
"ok": true,
"httpStatus": 200,
"responseId": "resp_ec8cc5ca92224ec2b612da70663f4c56",
"headersMs": 67.46184499998344,
"firstEventMs": 67.73573499999475,
"firstTokenMs": 606.3906669999706,
"totalDurationMs": 3432.989980000013,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 81,
"ok": true,
"httpStatus": 200,
"responseId": "resp_3eee4dd02037437eb841fc73f22517db",
"headersMs": 69.4163970000227,
"firstEventMs": 69.71951700001955,
"firstTokenMs": 301.09975600003963,
"totalDurationMs": 3056.2322470000363,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 82,
"ok": true,
"httpStatus": 200,
"responseId": "resp_d72947d2ad404f52997535a95b95011f",
"headersMs": 68.47833600000013,
"firstEventMs": 68.65966599999228,
"firstTokenMs": 365.3605669999961,
"totalDurationMs": 3119.6596769999596,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 83,
"ok": true,
"httpStatus": 200,
"responseId": "resp_53bb23c3ec984486816fe0a7b3356cd7",
"headersMs": 64.94479100004537,
"firstEventMs": 65.41758100001607,
"firstTokenMs": 433.445921000035,
"totalDurationMs": 3181.028844000015,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 84,
"ok": true,
"httpStatus": 200,
"responseId": "resp_615845b28b204abca134c97f4be691e3",
"headersMs": 66.93932200002018,
"firstEventMs": 67.14520299999276,
"firstTokenMs": 365.97475600003963,
"totalDurationMs": 3116.8880939999945,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 85,
"ok": true,
"httpStatus": 200,
"responseId": "resp_a2835e79ffdb4712947cce1d54866141",
"headersMs": 64.50649100000737,
"firstEventMs": 64.6376009999658,
"firstTokenMs": 423.20824999996694,
"totalDurationMs": 3176.4113299999735,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 86,
"ok": true,
"httpStatus": 200,
"responseId": "resp_e21a338ef3d5456fbf7d22b0dc7fa4bb",
"headersMs": 65.54703100002371,
"firstEventMs": 65.83017199998721,
"firstTokenMs": 368.35479900002247,
"totalDurationMs": 3125.6263340000296,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 87,
"ok": true,
"httpStatus": 200,
"responseId": "resp_2455dcaadd39410789f68afbe02e4cb6",
"headersMs": 69.01025600003777,
"firstEventMs": 69.15556600003038,
"firstTokenMs": 302.73753799998667,
"totalDurationMs": 3056.6928790000384,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 88,
"ok": true,
"httpStatus": 200,
"responseId": "resp_a36b724476884e11952ab9cf732d88e0",
"headersMs": 67.136874000018,
"firstEventMs": 67.52587400004268,
"firstTokenMs": 428.7453960000421,
"totalDurationMs": 3182.116046000039,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 89,
"ok": true,
"httpStatus": 200,
"responseId": "resp_f08dea23501b4a5ea6af424eb56b2aef",
"headersMs": 65.86319199996069,
"firstEventMs": 66.24425200000405,
"firstTokenMs": 300.2273649999988,
"totalDurationMs": 3055.9256079999614,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 90,
"ok": true,
"httpStatus": 200,
"responseId": "resp_91d760a6104940019dad78737c94d8d1",
"headersMs": 66.91690399998333,
"firstEventMs": 67.0718539999798,
"firstTokenMs": 490.16433299996424,
"totalDurationMs": 3243.595264000003,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 91,
"ok": true,
"httpStatus": 200,
"responseId": "resp_976adc595c7848b29c09f6f323b74a3b",
"headersMs": 66.92958299996099,
"firstEventMs": 67.21434399997815,
"firstTokenMs": 299.44922399998177,
"totalDurationMs": 3054.9395659999573,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 92,
"ok": true,
"httpStatus": 200,
"responseId": "resp_4659cbecdccd4632bffa5788319c42f5",
"headersMs": 66.06347300001653,
"firstEventMs": 66.28444299998228,
"firstTokenMs": 488.3706999999704,
"totalDurationMs": 3243.2691110000014,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 93,
"ok": true,
"httpStatus": 200,
"responseId": "resp_eb3753cc7a364e8cb66a5d31cd0c5d57",
"headersMs": 64.20200099999784,
"firstEventMs": 64.43368100002408,
"firstTokenMs": 295.1433889999753,
"totalDurationMs": 3085.329046000028,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 94,
"ok": true,
"httpStatus": 200,
"responseId": "resp_abd11ccaecad41ddb7509f541a5b57d1",
"headersMs": 70.41907800000627,
"firstEventMs": 70.69219799997518,
"firstTokenMs": 306.66871399997035,
"totalDurationMs": 3058.4967319999705,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 95,
"ok": true,
"httpStatus": 200,
"responseId": "resp_0d17ad910fea4294a39caf415fe2c2b8",
"headersMs": 65.62185200001113,
"firstEventMs": 65.77665199997136,
"firstTokenMs": 298.2719420000212,
"totalDurationMs": 3053.0366040000226,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 96,
"ok": true,
"httpStatus": 200,
"responseId": "resp_2c0173f809f54a46b900ed4b5de1188b",
"headersMs": 68.39882499998203,
"firstEventMs": 68.60042500001146,
"firstTokenMs": 490.4931220000144,
"totalDurationMs": 3245.777795000002,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 97,
"ok": true,
"httpStatus": 200,
"responseId": "resp_03af9cd6231746b49fd749c67badba0b",
"headersMs": 67.80904500000179,
"firstEventMs": 68.08453499997267,
"firstTokenMs": 298.6269929999835,
"totalDurationMs": 3053.2366369999945,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 98,
"ok": true,
"httpStatus": 200,
"responseId": "resp_3641dd6a179f46edaf48c3e762481289",
"headersMs": 63.37082900002133,
"firstEventMs": 63.55881999997655,
"firstTokenMs": 546.0431519999984,
"totalDurationMs": 3302.5070459999843,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 99,
"ok": true,
"httpStatus": 200,
"responseId": "resp_984e7eee765f4a82b9782cbe8096a7f3",
"headersMs": 67.75833500002045,
"firstEventMs": 68.0075160000124,
"firstTokenMs": 301.10184700001264,
"totalDurationMs": 3057.2031699999934,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
},
{
"sampleIndex": 100,
"ok": true,
"httpStatus": 200,
"responseId": "resp_29a71db294b84976be29ea1f303ab18f",
"headersMs": 67.71740399999544,
"firstEventMs": 68.06585499999346,
"firstTokenMs": 301.51615600002697,
"totalDurationMs": 3056.013098000025,
"eventCount": 137,
"textDeltaCount": 62,
"outputTextDeltaCount": 0,
"reasoningTextDeltaCount": 62,
"text": "Okay o usuário pediu para responder exatamente com \"OK\" e nada mais. Vou verificar se entendi corretamente. Ele quer que eu ignore qualquer outra coisa e só envie \"OK\". Não há necessidade de usar nenhuma ferramenta aqui, já que a resposta é"
}
]
}
```
# Activate a connector
Source: https://docs.mka1.com/api-reference/agent-connectors/activate-a-connector
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{id}/connectors/{connectorId}/activate
Revalidates the stored provider credentials and registers the provider webhook. Use this to retry a connector left in an error state. API-key authentication with every listed scope is required; session authentication is rejected, and the key must belong to the connector's original user or service-account principal so existing conversations keep the same owner.
# Create a connector
Source: https://docs.mka1.com/api-reference/agent-connectors/create-a-connector
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{id}/connectors
Connects the agent to a Telegram bot or WhatsApp Business phone number, validates the provider credentials, and registers the agent's webhook. WhatsApp connector support is beta. Text, photos, and gateway-supported documents can invoke the agent; inbound media additionally requires write:files. Managed outbound files require read:files, and generated images require both file scopes so their transient provider URLs can be materialized before delivery. The optional write:feedback scope enables native thumbs reaction synchronization to gateway response feedback. These conditional scopes are deliberately not part of x-required-scopes because text-only connectors do not need them. An API key with every listed scope is required; its identity tuple and current scopes are stored as a non-widening ceiling, then revalidated with mk-authentication before every connector run; session and delegated end-user contexts are rejected. The required access policy controls which provider users or chats may invoke the agent.
# Delete a connector
Source: https://docs.mka1.com/api-reference/agent-connectors/delete-a-connector
https://apigw.mka1.com/speakeasy.json delete /api/v1/agents/{id}/connectors/{connectorId}
Unregisters the connector-specific provider webhook and deletes the stored connector credentials. Telegram pending updates are dropped; WhatsApp deletion clears only the phone-number callback and does not unsubscribe other numbers in the business account.
# List connectors for an agent
Source: https://docs.mka1.com/api-reference/agent-connectors/list-connectors-for-an-agent
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{id}/connectors
Lists messaging-channel connectors configured for the agent. Connector credentials are never returned.
# Retrieve a connector
Source: https://docs.mka1.com/api-reference/agent-connectors/retrieve-a-connector
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{id}/connectors/{connectorId}
Retrieves connector configuration and status without exposing credentials.
# Set up a WhatsApp app webhook (Beta)
Source: https://docs.mka1.com/api-reference/agent-connectors/set-up-a-whatsapp-app-webhook-beta
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{id}/connectors/whatsapp/setup
Beta. Returns the app-level callback URL and verification token that must be saved in Meta before the first WhatsApp phone connector is created. The caller must be allowed to manage the agent. The stable verification token is returned only in this no-store response and is not a Meta access token.
# Approve or deny a pending MCP tool call
Source: https://docs.mka1.com/api-reference/agent-runs/approve-or-deny-a-pending-mcp-tool-call
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}/runs/{run_id}/mcp-approvals
Creates a continuation run for an mcp_approval_request emitted by the source run. The gateway binds the single-use decision to the original server, tool, and arguments; denying never invokes the remote MCP tool.
# Retrieve an agent run
Source: https://docs.mka1.com/api-reference/agent-runs/retrieve-an-agent-run
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{agent_id}/runs/{run_id}
# Stream agent run events
Source: https://docs.mka1.com/api-reference/agent-runs/stream-agent-run-events
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{agent_id}/runs/{run_id}/events
Streams Server-Sent Events for the gateway response linked to this agent run. Terminal runs emit a single terminal event and close.
# Wake a sleeping agent run
Source: https://docs.mka1.com/api-reference/agent-runs/wake-a-sleeping-agent-run
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}/runs/{run_id}/wake
Interrupts a short sleep tool call on a background run by forwarding follow-up input to the gateway response.
# Create an agent schedule
Source: https://docs.mka1.com/api-reference/agent-schedules/create-an-agent-schedule
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}/schedules
Creates a Temporal-backed one-time, interval, or cron schedule that starts normal saved agent runs.
# Delete an agent schedule
Source: https://docs.mka1.com/api-reference/agent-schedules/delete-an-agent-schedule
https://apigw.mka1.com/speakeasy.json delete /api/v1/agents/{agent_id}/schedules/{schedule_id}
# List schedules for an agent
Source: https://docs.mka1.com/api-reference/agent-schedules/list-schedules-for-an-agent
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{agent_id}/schedules
# Pause an agent schedule
Source: https://docs.mka1.com/api-reference/agent-schedules/pause-an-agent-schedule
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}/schedules/{schedule_id}/pause
# Resume an agent schedule
Source: https://docs.mka1.com/api-reference/agent-schedules/resume-an-agent-schedule
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}/schedules/{schedule_id}/resume
# Retrieve an agent schedule
Source: https://docs.mka1.com/api-reference/agent-schedules/retrieve-an-agent-schedule
https://apigw.mka1.com/speakeasy.json get /api/v1/agents/{agent_id}/schedules/{schedule_id}
# Update an agent schedule
Source: https://docs.mka1.com/api-reference/agent-schedules/update-an-agent-schedule
https://apigw.mka1.com/speakeasy.json post /api/v1/agents/{agent_id}/schedules/{schedule_id}
# Get Browser Session URL
Source: https://docs.mka1.com/api-reference/browser/get-browser-session-url
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/sessions/{session_id}/browser-url
Return the public gateway URL for a browser session's Chrome DevTools Protocol endpoint. Playwright can use this HTTP endpoint directly. For clients that require a WebSocket endpoint, request `json/version` and use its rewritten `webSocketDebuggerUrl`. Insert subpaths before the query string; for example, use `/ports/9222/json/version?session_token=...`. Send the same MKA1 API-key authorization header on the HTTP and WebSocket requests. Standard sessions do not expose a public URL; use the command, code, and workspace operations instead.
# Get Browser Session URL (Deprecated)
Source: https://docs.mka1.com/api-reference/browser/get-browser-session-url-deprecated
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/sessions/{session_id}/url
Deprecated compatibility alias for `getBrowserUrl`. Return the public gateway URL for a browser session's Chrome DevTools Protocol endpoint. Standard sessions do not expose a public URL; use the command, code, and workspace operations instead.
# Proxy Browser Port Request
Source: https://docs.mka1.com/api-reference/browser/proxy-browser-port-request
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/sessions/{session_id}/ports/{port}/{subpath}
Proxy an HTTP request to an exposed browser-session port through the gateway. Use the URL returned by `GET /sessions/{session_id}/browser-url` as the base. Insert CDP subpaths such as `json/version` or `json/list` before its query string, preserving the `session_token` parameter. This low-level proxy is intended for browser sessions on port `9222` and still requires the normal MKA1 API-key authorization header.
# Cancel an eval run
Source: https://docs.mka1.com/api-reference/evals/cancel-an-eval-run
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/runs/{run_id}/cancel
Requests cancellation for a queued or running eval run.
# Count tokens from stored text for a suite's unmeasured samples
Source: https://docs.mka1.com/api-reference/evals/count-tokens-from-stored-text-for-a-suites-unmeasured-samples
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/suites/{suite_id}/tokens/measure
Backfill for rows written before the gateway recorded usage. For samples of the suite's completed runs that have answer or reasoning text but no token figure, counts prompt, reasoning and answer tokens from the stored text (tiktoken o200k_base, one ruler for every model), marks them `tokens_estimated`, and refreshes each run's per-task `tokens` and run totals so the leaderboard's efficiency figures appear. Processes `limit` runs per call, oldest run id first; call again until `remaining_runs` is 0. Samples the provider or the import already measured are left alone, and a sample with no text stays unmeasured. New rows get the same figures at generation or import time, so this is a no-op on a suite with nothing to measure.
# Create an eval run
Source: https://docs.mka1.com/api-reference/evals/create-an-eval-run
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/runs
Starts a durable eval run over the selected suite version, tasks, and models.
# Create an eval suite
Source: https://docs.mka1.com/api-reference/evals/create-an-eval-suite
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/suites
Creates a team-scoped declarative eval suite. Dataset and Python grader files must be uploaded separately with purpose 'evals'.
# Create an eval suite version
Source: https://docs.mka1.com/api-reference/evals/create-an-eval-suite-version
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/suites/{suite_id}/versions
Creates an immutable suite version. Use this endpoint for edits to an existing eval suite.
# Delete an eval run
Source: https://docs.mka1.com/api-reference/evals/delete-an-eval-run
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/evals/runs/{run_id}
Soft-deletes an eval run so it no longer appears in run lists, details, or score leaderboards.
# Delete an eval suite
Source: https://docs.mka1.com/api-reference/evals/delete-an-eval-suite
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/evals/suites/{suite_id}
Soft-deletes an eval suite and all of its eval runs so they no longer appear in user-facing reads.
# Get an eval run
Source: https://docs.mka1.com/api-reference/evals/get-an-eval-run
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/runs/{run_id}
Retrieves an eval run by ID.
# Get an eval suite
Source: https://docs.mka1.com/api-reference/evals/get-an-eval-suite
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/suites/{suite_id}
Retrieves an eval suite by ID.
# Get an eval suite version
Source: https://docs.mka1.com/api-reference/evals/get-an-eval-suite-version
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/suites/{suite_id}/versions/{version}
Retrieves an immutable eval suite version and its manifest.
# Get the coding-agent leaderboard for an eval suite
Source: https://docs.mka1.com/api-reference/evals/get-the-coding-agent-leaderboard-for-an-eval-suite
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/suites/{suite_id}/leaderboard
Ranks the suite's completed coding-agent runs, one row per (agent, model, effort). Only runs that recorded an `agent_name` participate — a QA or transcription run of the same suite has no agent to attribute a score to and is not a board row. `accuracy` is the mean of `metric` (default `reward`) over the row's scored trials, and `accuracy_ci` is the 95% Wald interval around it; both are derived per request rather than stored, so rerunning a failed trial moves them instead of leaving a stale copy behind. `agent_version` is reported but is not part of the row identity, so an agent upgrade does not split a row in two. Rows are ordered by accuracy descending, nulls last. Pass `suite_version` when the suite has more than one, otherwise the board mixes task sets.
# List eval runs
Source: https://docs.mka1.com/api-reference/evals/list-eval-runs
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/runs
Returns eval runs visible to the authenticated team context. suite_version is a per-suite ordinal and must be paired with suite_id; supplying it alone returns 400.
# List eval suite versions
Source: https://docs.mka1.com/api-reference/evals/list-eval-suite-versions
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/suites/{suite_id}/versions
Returns immutable versions for an eval suite, including each version manifest.
# List eval suites
Source: https://docs.mka1.com/api-reference/evals/list-eval-suites
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/suites
Returns eval suites visible to the authenticated team context.
# List leaderboard runs for an eval suite
Source: https://docs.mka1.com/api-reference/evals/list-leaderboard-runs-for-an-eval-suite
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/suites/{suite_id}/leaderboard-runs
Returns each ranking group's most recent completed runs for a suite in one request, with the group assignments in `groups`. A group is (model, targeted task) for task_ids-restricted runs and (model) for unrestricted runs (task_id null). Build boards from `groups`, not from run.models/run.task_ids — a returned run may name models or tasks whose groups it did not rank in. `truncated: true` means a server ceiling trimmed the aggregate; whole runs are kept in (best rank, first model, first task, id) order, so every group's newest runs survive before any group's fallbacks and no group is dropped for being old. Resume a truncated board by passing `next_cursor` back as `cursor` and unioning the responses. See the evals docs for grouping rationale and cost characteristics.
# Rerun failed eval samples
Source: https://docs.mka1.com/api-reference/evals/rerun-failed-eval-samples
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/runs/{run_id}/rerun-failed
Queues a completed eval run to retry only samples with sample status 'failed'. Retried samples keep the same run ID and sample IDs, replacing errored sample results in place.
# Run Code
Source: https://docs.mka1.com/api-reference/execution/run-code
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions/{session_id}/code
Execute source code in the session workspace using a supported runtime and return the execution result.
# Run Command
Source: https://docs.mka1.com/api-reference/execution/run-command
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions/{session_id}/commands
Run a command in the session workspace and return stdout, stderr, exit code, and changed files.
# Create MCP credential
Source: https://docs.mka1.com/api-reference/mcp-vault/create-mcp-credential
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/mcp/servers/{server_id}/credentials
Stores encrypted credentials for a user-owned MCP server. Secret values are never returned.
# Create MCP server
Source: https://docs.mka1.com/api-reference/mcp-vault/create-mcp-server
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/mcp/servers
Creates a user-owned MCP server configuration. Secret credentials are stored separately.
# Delete MCP credential
Source: https://docs.mka1.com/api-reference/mcp-vault/delete-mcp-credential
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/mcp/credentials/{credential_id}
Revokes a user-owned MCP credential.
# Delete MCP server
Source: https://docs.mka1.com/api-reference/mcp-vault/delete-mcp-server
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/mcp/servers/{server_id}
Soft-deletes a user-owned MCP server and revokes its credentials.
# List MCP credentials
Source: https://docs.mka1.com/api-reference/mcp-vault/list-mcp-credentials
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/mcp/servers/{server_id}/credentials
Lists encrypted credential metadata for a user-owned MCP server.
# List MCP servers
Source: https://docs.mka1.com/api-reference/mcp-vault/list-mcp-servers
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/mcp/servers
Lists MCP server configurations owned by the authenticated user context.
# Retrieve MCP server
Source: https://docs.mka1.com/api-reference/mcp-vault/retrieve-mcp-server
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/mcp/servers/{server_id}
Returns a user-owned MCP server configuration.
# Test MCP server
Source: https://docs.mka1.com/api-reference/mcp-vault/test-mcp-server
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/mcp/servers/{server_id}/test
Connects to an MCP server using the authenticated user's stored credential and returns discovered tool names. Failed connections return a 502 error; connection details are retained in redacted server logs.
# Update MCP server
Source: https://docs.mka1.com/api-reference/mcp-vault/update-mcp-server
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/mcp/servers/{server_id}
Partially updates a user-owned MCP server configuration.
# Create memory entry
Source: https://docs.mka1.com/api-reference/memory-stores/create-memory-entry
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/memory_stores/{memory_store_id}/entries
# Create memory store
Source: https://docs.mka1.com/api-reference/memory-stores/create-memory-store
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/memory_stores
Creates a memory store for persistent agent notes. Stores are private by default and can be shared across the workspace.
# Delete memory entry
Source: https://docs.mka1.com/api-reference/memory-stores/delete-memory-entry
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/memory_stores/{memory_store_id}/entries/{entry_id}
# Delete memory store
Source: https://docs.mka1.com/api-reference/memory-stores/delete-memory-store
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/memory_stores/{memory_store_id}
# List memory entries
Source: https://docs.mka1.com/api-reference/memory-stores/list-memory-entries
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/memory_stores/{memory_store_id}/entries
# List memory stores
Source: https://docs.mka1.com/api-reference/memory-stores/list-memory-stores
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/memory_stores
# Retrieve memory entry
Source: https://docs.mka1.com/api-reference/memory-stores/retrieve-memory-entry
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/memory_stores/{memory_store_id}/entries/{entry_id}
# Retrieve memory store
Source: https://docs.mka1.com/api-reference/memory-stores/retrieve-memory-store
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/memory_stores/{memory_store_id}
# Update memory entry
Source: https://docs.mka1.com/api-reference/memory-stores/update-memory-entry
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/memory_stores/{memory_store_id}/entries/{entry_id}
# Update memory store
Source: https://docs.mka1.com/api-reference/memory-stores/update-memory-store
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/memory_stores/{memory_store_id}
# Create Environment
Source: https://docs.mka1.com/api-reference/sandbox-environments/create-environment
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/environments
Save a named environment: repositories to clone, environment variables, network access, and an optional bash setup script. Sessions created from it copy these settings. Do not put secrets in `environment_variables`.
# Delete Environment
Source: https://docs.mka1.com/api-reference/sandbox-environments/delete-environment
https://apigw.mka1.com/speakeasy.json delete /api/v1/sandbox/environments/{environment_id}
Delete a saved environment. Sessions already created from it are not affected.
# Get Environment
Source: https://docs.mka1.com/api-reference/sandbox-environments/get-environment
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/environments/{environment_id}
Return one of the caller's saved environments.
# List Environments
Source: https://docs.mka1.com/api-reference/sandbox-environments/list-environments
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/environments
List the caller's saved environments, plus the per-environment repository limit.
# Run Environment Setup
Source: https://docs.mka1.com/api-reference/sandbox-environments/run-environment-setup
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions/{session_id}/environment-setup
Run the setup script of the environment the session was created from. Call it once the session's repositories have cloned. A `running` status means setup has not finished yet and calling again is safe; once setup has succeeded, later calls return `succeeded` without running it again.
# Update Environment
Source: https://docs.mka1.com/api-reference/sandbox-environments/update-environment
https://apigw.mka1.com/speakeasy.json put /api/v1/sandbox/environments/{environment_id}
Replace a saved environment's settings. Omit `network_access` to keep the stored value. Sessions already created from the environment keep the settings they started with.
# Add Session Repository
Source: https://docs.mka1.com/api-reference/sandbox-github/add-session-repository
https://apigw.mka1.com/speakeasy.json put /api/v1/sandbox/sessions/{session_id}/github/repositories/{repository_id}
Add a connected repository to the session and clone it at `ref`, or at the default branch when `ref` is omitted. Repeating the same request is safe. After a successful clone the repository's ref cannot change.
# Clone GitHub Repository into Session
Source: https://docs.mka1.com/api-reference/sandbox-github/clone-github-repository-into-session
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions/{session_id}/github/read-clone
Clone a connected repository at `base_sha` into the session workspace using the caller's GitHub connection. The sandbox host runs the clone, so the token never enters the session.
# Connect GitHub Account
Source: https://docs.mka1.com/api-reference/sandbox-github/connect-github-account
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/github/oauth/connections
Finish GitHub authorization by exchanging the `code` and `state` from GitHub's redirect for a stored connection. The sandbox service keeps the access token encrypted and never returns it. The response lists the repositories the connection can reach.
# Create or Update Pull Request
Source: https://docs.mka1.com/api-reference/sandbox-github/create-or-update-pull-request
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions/{session_id}/github/pull-request
Open a pull request from `branch` in the session's repository, or update the one already recorded for that branch, reopening it if it was closed. The base defaults to the repository's default branch. A merged pull request is never reopened; a later call for the same branch opens a new one. The session does not need to be running.
# Disconnect GitHub Account
Source: https://docs.mka1.com/api-reference/sandbox-github/disconnect-github-account
https://apigw.mka1.com/speakeasy.json delete /api/v1/sandbox/github/oauth/connections
Delete the caller's GitHub connection and revoke its token at GitHub. The connection is deleted even if GitHub does not confirm the revocation.
# Dismiss Failed Session Repository
Source: https://docs.mka1.com/api-reference/sandbox-github/dismiss-failed-session-repository
https://apigw.mka1.com/speakeasy.json delete /api/v1/sandbox/sessions/{session_id}/github/repositories/{repository_id}
Remove a repository whose clone failed from the session. A repository that cloned successfully, or whose clone is still in progress, cannot be removed.
# Get GitHub Connection
Source: https://docs.mka1.com/api-reference/sandbox-github/get-github-connection
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/github/oauth/connections
Return the caller's GitHub connection, or `null` when there is none. `token_invalid_at` is set once GitHub has rejected the stored token; reconnect to fix it. Set `verify` to `true` to check the token with GitHub now instead of at its next use.
# List GitHub Repositories
Source: https://docs.mka1.com/api-reference/sandbox-github/list-github-repositories
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/github/repositories
List the repositories recorded for the caller's GitHub connection, or an empty list when there is no connection. The list is captured when you connect; call `POST /github/repositories/refresh` to update it.
# List Session Repositories
Source: https://docs.mka1.com/api-reference/sandbox-github/list-session-repositories
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/sessions/{session_id}/github/repositories
Return the repositories added to the session with each one's ref, checkout path, clone status, last push, and pull request, plus the per-session repository limit.
# Push Session to GitHub
Source: https://docs.mka1.com/api-reference/sandbox-github/push-session-to-github
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions/{session_id}/github/push
Push the session's checkout to `branch` in the repository it was cloned from, using the caller's GitHub connection. The repository always comes from the session, never from the request. Set `checkout_path` when the repository is not at the workspace root.
# Refresh GitHub Repositories
Source: https://docs.mka1.com/api-reference/sandbox-github/refresh-github-repositories
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/github/repositories/refresh
Re-read the repositories the caller's GitHub connection can reach, save them as the connection's repository list, and return it.
# Resolve GitHub Reference
Source: https://docs.mka1.com/api-reference/sandbox-github/resolve-github-reference
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/github/repositories/resolve
Resolve a Git reference in a connected repository to a commit SHA. Omit `ref` to resolve the repository's default branch.
# Start GitHub Authorization
Source: https://docs.mka1.com/api-reference/sandbox-github/start-github-authorization
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/github/oauth/intents
Start connecting the caller's GitHub account. Send the user to the returned `authorize_url`. GitHub redirects back with a `code` and the same `state`; pass both to `POST /github/oauth/connections` before `expires_in_seconds` elapses. Each `state` works once.
# Get Sandbox Pricing
Source: https://docs.mka1.com/api-reference/sandbox-pricing/get-sandbox-pricing
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/pricing
Current sandbox pricing rate card, keyed by SKU (`standard`, `browser`, `eval-python`). Metered sandbox usage is billed `hours × (per_hour + reserved_memory_GiB × per_gib_hour)`; SKUs without a configured rate accrue no spend. Cluster admins only.
# Set Sandbox Pricing
Source: https://docs.mka1.com/api-reference/sandbox-pricing/set-sandbox-pricing
https://apigw.mka1.com/speakeasy.json put /api/v1/sandbox/pricing
Replace the sandbox pricing rate card. Full-replace semantics. Omitting a SKU that currently has a price is refused with 422 unless `allow_unpriced` is true: an unpriced SKU accrues no spend and its usage cannot be billed. A `currency` that differs from the stored one is saved only after the budgeting service accepts it as the cluster's billing currency (409 when it conflicts, 503 when it cannot be verified). Takes effect on the next meter window without a restart. Cluster admins only.
# Get Sandbox Usage
Source: https://docs.mka1.com/api-reference/sandbox-usage/get-sandbox-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/usage
Aggregate sandbox usage (session lifecycle, execution, and workspace operations) over a time range, bucketed and optionally grouped. Buckets are calendar-aligned in UTC: `start_time` is snapped down and `end_time` snapped up to the nearest bucket-width boundary, so the first and last buckets may extend slightly beyond the requested range. Org-scoped: callers see their own usage, org admins their team's; cluster admins may pass `all_orgs` or `org_ids`. Cost and spend reporting lives in the budgeting API (`/api/v1/budgeting/usage/costs`).
# Create Session
Source: https://docs.mka1.com/api-reference/sessions/create-session
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions
Create a sandbox session and return its public session metadata, session token, and provider. Set `session_kind` to `browser` to start a browser-backed session instead of a standard command/code sandbox. Set `queue_if_full` to `true` to queue the request instead of failing when runner capacity is temporarily unavailable. It does not queue requests for session kinds the deployment does not support. Browser sessions require a Firecracker-backed deployment; standard-only deployments reject them immediately with `browser_sessions_not_enabled`.
# Get Session
Source: https://docs.mka1.com/api-reference/sessions/get-session
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/sessions/{session_id}
Return the current state, configuration, and resource allocation for a sandbox session.
# List Sessions
Source: https://docs.mka1.com/api-reference/sessions/list-sessions
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/sessions
List sandbox sessions visible to the authenticated caller.
# Terminate Session
Source: https://docs.mka1.com/api-reference/sessions/terminate-session
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions/{session_id}/terminate
Stop a sandbox session and release the backing sandbox resources.
# Create skill
Source: https://docs.mka1.com/api-reference/skills/create-skill
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/skills
Create a new skill by uploading files. The uploaded files must include a SKILL.md manifest. Accepts multipart form data with individual files or a single zip archive.
# Create skill version
Source: https://docs.mka1.com/api-reference/skills/create-skill-version
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/skills/{skill_id}/versions
Create a new immutable version of a skill by uploading files. The uploaded files must include a SKILL.md manifest.
# Delete skill
Source: https://docs.mka1.com/api-reference/skills/delete-skill
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/skills/{skill_id}
Delete a skill and all its versions.
# Delete skill version
Source: https://docs.mka1.com/api-reference/skills/delete-skill-version
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/skills/{skill_id}/versions/{version}
Delete a specific version of a skill.
# Download skill content
Source: https://docs.mka1.com/api-reference/skills/download-skill-content
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/skills/{skill_id}/content
Download the zip bundle for a skill's default version.
# Download skill version content
Source: https://docs.mka1.com/api-reference/skills/download-skill-version-content
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/skills/{skill_id}/versions/{version}/content
Download the zip bundle for a specific skill version.
# List preconfigured skills
Source: https://docs.mka1.com/api-reference/skills/list-preconfigured-skills
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/skills/preconfigured
Returns the list of preconfigured skills that ship with the gateway. These can be referenced in shell tool definitions as { type: 'preconfigured', name: '...' }.
# List skill versions
Source: https://docs.mka1.com/api-reference/skills/list-skill-versions
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/skills/{skill_id}/versions
Returns a paginated list of versions for a skill.
# List skills
Source: https://docs.mka1.com/api-reference/skills/list-skills
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/skills
Returns a paginated list of skills.
# Retrieve skill
Source: https://docs.mka1.com/api-reference/skills/retrieve-skill
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/skills/{skill_id}
Returns information about a specific skill.
# Retrieve skill version
Source: https://docs.mka1.com/api-reference/skills/retrieve-skill-version
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/skills/{skill_id}/versions/{version}
Returns information about a specific skill version.
# Update skill
Source: https://docs.mka1.com/api-reference/skills/update-skill
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/skills/{skill_id}
Update the default version pointer for a skill.
# Download Workspace Archive
Source: https://docs.mka1.com/api-reference/workspace/download-workspace-archive
https://apigw.mka1.com/speakeasy.json post /api/v1/sandbox/sessions/{session_id}/workspace/archive
Download a zip archive containing the selected workspace paths.
# Download Workspace File
Source: https://docs.mka1.com/api-reference/workspace/download-workspace-file
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/sessions/{session_id}/workspace/files/{file_path}
Download raw bytes from a file in the session workspace.
# Get Workspace Manifest
Source: https://docs.mka1.com/api-reference/workspace/get-workspace-manifest
https://apigw.mka1.com/speakeasy.json get /api/v1/sandbox/sessions/{session_id}/workspace
List files currently stored in the session workspace, including paths, sizes, and etags.
# Upload Workspace Archive
Source: https://docs.mka1.com/api-reference/workspace/upload-workspace-archive
https://apigw.mka1.com/speakeasy.json put /api/v1/sandbox/sessions/{session_id}/workspace/archive
Upload a zip archive and extract its files into the session workspace.
# Upload Workspace File
Source: https://docs.mka1.com/api-reference/workspace/upload-workspace-file
https://apigw.mka1.com/speakeasy.json put /api/v1/sandbox/sessions/{session_id}/workspace/files/{file_path}
Upload raw bytes into the session workspace at the given path.
# Create a quote
Source: https://docs.mka1.com/api-reference/compute-catalog/create-a-quote
https://apigw.mka1.com/speakeasy.json post /api/v1/compute/catalog/quotes
# Get an accelerator
Source: https://docs.mka1.com/api-reference/compute-catalog/get-an-accelerator
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/catalog/accelerators/{name}
# List accelerators
Source: https://docs.mka1.com/api-reference/compute-catalog/list-accelerators
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/catalog/accelerators
# List provider health
Source: https://docs.mka1.com/api-reference/compute-catalog/list-provider-health
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/catalog/providers
Cluster administrators may always read this route. Organization administrators may read it only when provider anonymity is disabled.
# List provider offers
Source: https://docs.mka1.com/api-reference/compute-catalog/list-provider-offers
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/catalog/offers
Cluster administrators may always read this route. Organization administrators may read it only when provider anonymity is disabled.
# Create a job
Source: https://docs.mka1.com/api-reference/compute-jobs/create-a-job
https://apigw.mka1.com/speakeasy.json post /api/v1/compute/jobs
# Get a job
Source: https://docs.mka1.com/api-reference/compute-jobs/get-a-job
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/jobs/{id}
# List job events
Source: https://docs.mka1.com/api-reference/compute-jobs/list-job-events
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/jobs/{id}/events
# List job logs
Source: https://docs.mka1.com/api-reference/compute-jobs/list-job-logs
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/jobs/{id}/logs
# List jobs
Source: https://docs.mka1.com/api-reference/compute-jobs/list-jobs
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/jobs
# List observed job instances
Source: https://docs.mka1.com/api-reference/compute-jobs/list-observed-job-instances
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/jobs/{id}/instances
# Terminate a job
Source: https://docs.mka1.com/api-reference/compute-jobs/terminate-a-job
https://apigw.mka1.com/speakeasy.json post /api/v1/compute/jobs/{id}/terminate
# Create an immutable storage-price version
Source: https://docs.mka1.com/api-reference/compute-pricing/create-an-immutable-storage-price-version
https://apigw.mka1.com/speakeasy.json put /api/v1/compute/pricing
Cluster administrators only. If-Match: 0 performs the explicit bootstrap. Every version activates at the next UTC-hour boundary; equivalent idempotent replay precedes version comparison.
# Get the latest committed storage price
Source: https://docs.mka1.com/api-reference/compute-pricing/get-the-latest-committed-storage-price
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/pricing
The latest version may be scheduled for the next UTC hour. Before the first version is written this route returns pricing_not_configured.
# Create a secret
Source: https://docs.mka1.com/api-reference/compute-secrets/create-a-secret
https://apigw.mka1.com/speakeasy.json post /api/v1/compute/secrets
# Delete a secret
Source: https://docs.mka1.com/api-reference/compute-secrets/delete-a-secret
https://apigw.mka1.com/speakeasy.json delete /api/v1/compute/secrets/{id}
# Get a secret
Source: https://docs.mka1.com/api-reference/compute-secrets/get-a-secret
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/secrets/{id}
# List secrets
Source: https://docs.mka1.com/api-reference/compute-secrets/list-secrets
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/secrets
# Create a service
Source: https://docs.mka1.com/api-reference/compute-services/create-a-service
https://apigw.mka1.com/speakeasy.json post /api/v1/compute/services
# Get a service
Source: https://docs.mka1.com/api-reference/compute-services/get-a-service
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/services/{id}
# List observed service instances
Source: https://docs.mka1.com/api-reference/compute-services/list-observed-service-instances
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/services/{id}/instances
# List service events
Source: https://docs.mka1.com/api-reference/compute-services/list-service-events
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/services/{id}/events
# List service logs
Source: https://docs.mka1.com/api-reference/compute-services/list-service-logs
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/services/{id}/logs
# List services
Source: https://docs.mka1.com/api-reference/compute-services/list-services
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/services
# Replace a service scaling policy
Source: https://docs.mka1.com/api-reference/compute-services/replace-a-service-scaling-policy
https://apigw.mka1.com/speakeasy.json patch /api/v1/compute/services/{id}/scaling
# Terminate a service
Source: https://docs.mka1.com/api-reference/compute-services/terminate-a-service
https://apigw.mka1.com/speakeasy.json post /api/v1/compute/services/{id}/terminate
# Get a tenant
Source: https://docs.mka1.com/api-reference/compute-tenants/get-a-tenant
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/tenants/{org_id}
Cluster-administrator-only.
# List tenants
Source: https://docs.mka1.com/api-reference/compute-tenants/list-tenants
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/tenants
Cluster-administrator-only.
# Update a tenant
Source: https://docs.mka1.com/api-reference/compute-tenants/update-a-tenant
https://apigw.mka1.com/speakeasy.json put /api/v1/compute/tenants/{org_id}
Cluster-administrator-only idempotent upsert.
# Get usage
Source: https://docs.mka1.com/api-reference/compute-usage/get-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/usage
# Create a standalone shared volume
Source: https://docs.mka1.com/api-reference/compute-volumes/create-a-standalone-shared-volume
https://apigw.mka1.com/speakeasy.json post /api/v1/compute/volumes
# Get a standalone volume
Source: https://docs.mka1.com/api-reference/compute-volumes/get-a-standalone-volume
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/volumes/{id}
# List organization volumes
Source: https://docs.mka1.com/api-reference/compute-volumes/list-organization-volumes
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/volumes
# List volume attachments
Source: https://docs.mka1.com/api-reference/compute-volumes/list-volume-attachments
https://apigw.mka1.com/speakeasy.json get /api/v1/compute/volumes/{id}/attachments
# Permanently delete a standalone volume
Source: https://docs.mka1.com/api-reference/compute-volumes/permanently-delete-a-standalone-volume
https://apigw.mka1.com/speakeasy.json delete /api/v1/compute/volumes/{id}
Deletion bypasses tenant enablement and budget gates, but is refused while non-terminal attachments exist.
# Append trials to an open coding-agent run
Source: https://docs.mka1.com/api-reference/evals/append-trials-to-an-open-coding-agent-run
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/runs/{run_id}/trials
Adds finished trials to a run opened with `finalize: false`, so a job started from MKA1 can be watched while it runs instead of appearing complete out of nowhere at the end. Each trial pins its own `sample_index` and upserts on (task, model, sample_index): a harness cannot tell a timeout from a lost response, so re-sending a batch is safe and replaces rather than duplicates. The whole batch and its aggregate recompute land in one transaction, serialized per run. Counts, metrics and cost are recomputed from the stored rows on every call, never accumulated from the request, so a replayed batch cannot double them. Send `finalize: true` (usually with an empty `trials`) to close the run — until then it stays `in_progress` and off the leaderboards, which only count completed runs. Appending to an already-completed or cancelled run is rejected: that record is finished, and rewriting it would silently move a number someone may have already read.
# Create an eval schedule
Source: https://docs.mka1.com/api-reference/evals/create-an-eval-schedule
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/schedules
Schedules an eval run to fire on a cron or interval cadence, with optional webhook notifications of run status.
# Delete an eval schedule
Source: https://docs.mka1.com/api-reference/evals/delete-an-eval-schedule
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/evals/schedules/{schedule_id}
Soft-deletes an eval schedule and removes its Temporal schedule. Historical runs are preserved.
# Get an eval run overview
Source: https://docs.mka1.com/api-reference/evals/get-an-eval-run-overview
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/runs/{run_id}/overview
Aggregate header for one run's trials view: trial counts, average reward, cost, and the input/output/cached token split. Its own route rather than fields on the run object because it scans the run's samples — folding it into `GET /evals/runs/{run_id}` would charge that scan to every run list and to the status polling that runs for the whole length of an eval. `trials.errored` overlaps `trials.failed` instead of partitioning it: a coding-agent trial can carry an agent timeout in `error` and still be completed and scored. `trials.retried` counts trials rerun through rerun-failed, read from the pre-rerun snapshot, since a rerun overwrites the sample in place.
# Get an eval sample trajectory
Source: https://docs.mka1.com/api-reference/evals/get-an-eval-sample-trajectory
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/runs/{run_id}/samples/{sample_index}/trajectory
Returns one coding-agent trial's session — the steps the agent took, verbatim in the harness's interchange format (see `schema_version`, e.g. `ATIF-v1.7`). Deliberately not part of the samples list: a trajectory averages ~92 KB and that list pages up to 500 rows. Sample indices are unique per (task, model), not per run, so pass `task_id` and/or `model` when the run covers more than one; an index that matches several trials returns 400 rather than guessing, and never falls back to another trial's session. Returns 404 when the sample does not exist or recorded no trajectory.
# Get an eval schedule
Source: https://docs.mka1.com/api-reference/evals/get-an-eval-schedule
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/schedules/{schedule_id}
Retrieves an eval schedule by ID, including the next scheduled fire time from Temporal when resolvable.
# Get eval run artifacts
Source: https://docs.mka1.com/api-reference/evals/get-eval-run-artifacts
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/runs/{run_id}/artifacts
Returns generated result and sample artifact file IDs for a completed eval run.
# Get eval sample audio
Source: https://docs.mka1.com/api-reference/evals/get-eval-sample-audio
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/runs/{run_id}/samples/{sample_index}/audio
Returns `{ object, audio, sample_index, task_id, model }` for a single transcription sample — the clip reference (a base64 `data:` URI or a URL) read from the un-redacted `dataset_row` (list responses redact inline `data:` blobs), plus the resolved task/model. Prefers the task's configured `audio_column`, falling back to a heuristic scan. The clip differs across tasks, so pass `task_id` when a run has more than one transcription task; if the index spans multiple tasks and `task_id` is omitted, returns 400 rather than guessing. `model` is optional (the clip is identical across models) and only extends the index prefix. Returns 404 when the sample or its audio is absent, 413 when the inline clip is too large. Returns 503 when object storage is briefly unreachable, as distinct from 404 for a clip that is genuinely gone.
# Import a finished coding-agent run
Source: https://docs.mka1.com/api-reference/evals/import-a-finished-coding-agent-run
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/imports/agent-run
Uploads one completed harness job — the run and its trials — directly, so results never round-trip through external storage the way the Hugging Face importer does. Every `task_id` must already exist in the target suite version's manifest; unknown ids are rejected rather than invented, because a typo would otherwise import as a task the suite does not have and read as a model that never covered the version. The run is recorded as `completed` and is not executed: this is a write, not a run request, so no workflow is started. Trials that cover every task of the version get `task_ids: null`, which is what lets the run rank as a complete sweep. Trajectories are NOT part of this payload — a full 91-task run measured 8.3 MB of them — so upload each one against `PUT /evals/runs/{run_id}/samples/{sample_index}/trajectory` afterwards. Pass `idempotency_key` and a retried upload returns the first run instead of doubling the trials behind a board row.
# Import historical eval results from Hugging Face
Source: https://docs.mka1.com/api-reference/evals/import-historical-eval-results-from-hugging-face
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/imports/huggingface-results
Imports simplified historical samples.jsonl-style eval results from a Hugging Face dataset repository into a completed eval suite run shape. Aggregates are recomputed from samples and include canonical score metrics for leaderboards.
# List eval samples
Source: https://docs.mka1.com/api-reference/evals/list-eval-samples
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/runs/{run_id}/samples
Returns prompt, target, model output, extraction, score, and judge details for an eval run.
# List eval schedules
Source: https://docs.mka1.com/api-reference/evals/list-eval-schedules
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/schedules
Returns eval schedules visible to the authenticated team context.
# List runs created by an eval schedule
Source: https://docs.mka1.com/api-reference/evals/list-runs-created-by-an-eval-schedule
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/evals/schedules/{schedule_id}/runs
Returns eval runs that were created by the given schedule. suite_version may be used without suite_id here, since the schedule already pins the suite; supplying a suite_id that is not the schedule's returns 400.
# Retry an eval run
Source: https://docs.mka1.com/api-reference/evals/retry-an-eval-run
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/runs/{run_id}/retry
Queues a failed or cancelled eval run to retry in place. Completed samples keep their results, generated-but-unscored cancelled samples resume at scoring, unfinished samples are requeued, and runs with no persisted samples are prepared from scratch with the same run ID.
# Trigger an eval schedule now
Source: https://docs.mka1.com/api-reference/evals/trigger-an-eval-schedule-now
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/evals/schedules/{schedule_id}/trigger
Fires the schedule immediately, in addition to its normal cadence.
# Update an eval schedule
Source: https://docs.mka1.com/api-reference/evals/update-an-eval-schedule
https://apigw.mka1.com/speakeasy.json patch /api/v1/llm/evals/schedules/{schedule_id}
Updates an eval schedule's cadence, run config, webhook, overlap policy, or enabled state.
# Upload an eval sample trajectory
Source: https://docs.mka1.com/api-reference/evals/upload-an-eval-sample-trajectory
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/evals/runs/{run_id}/samples/{sample_index}/trajectory
Stores one coding-agent trial's session, in whatever interchange format the harness produced (record it in `schema_version`, e.g. `ATIF-v1.7`). `steps` is stored verbatim and never validated, so a harness format change needs no gateway release. Separate from the run import because a trajectory averages ~92 KB and a whole run's worth would not fit in one request. Upserts, so re-sending after a timeout replaces the trajectory rather than failing. Sample indices are unique per (task, model), not per run, so pass `task_id` and/or `model` when the run covers more than one — an ambiguous index returns 400 rather than writing to the wrong trial. Rejects a payload whose `steps` and `logs` together exceed 16 MiB with 413.
# Batch retrieve feedback for multiple completions
Source: https://docs.mka1.com/api-reference/feedback/batch-retrieve-feedback-for-multiple-completions
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/feedback/completions/batch
Retrieves feedback for multiple chat completions in a single batch request.
# Batch retrieve feedback for multiple responses
Source: https://docs.mka1.com/api-reference/feedback/batch-retrieve-feedback-for-multiple-responses
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/feedback/responses/batch
Retrieves feedback for multiple agent responses in a single batch request.
# Export completion feedback as CSV
Source: https://docs.mka1.com/api-reference/feedback/export-completion-feedback-as-csv
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/feedback/export/completions
Synchronously exports the completion feedback entries visible to the caller as a CSV file, ordered by the creation date of the underlying request. Visibility matches the list endpoint: callers see their own feedback; org owners and admins see their whole team. Supports filtering by rating. The export is capped at 50,000 rows; when the cap is hit the response carries an X-Export-Truncated header and older rows (with the default descending order) are omitted.
# Export response feedback as CSV
Source: https://docs.mka1.com/api-reference/feedback/export-response-feedback-as-csv
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/feedback/export/responses
Synchronously exports the response feedback entries visible to the caller as a CSV file, ordered by the creation date of the underlying request. Visibility matches the list endpoint: callers see their own feedback; org owners and admins see their whole team. Supports filtering by rating. The export is capped at 50,000 rows; when the cap is hit the response carries an X-Export-Truncated header and older rows (with the default descending order) are omitted.
# Get feedback export status
Source: https://docs.mka1.com/api-reference/feedback/get-feedback-export-status
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/feedback/export/status
Checks the status and progress of the currently running or most recently completed feedback export job. Restricted to cluster administrators.
# List chat completion feedback
Source: https://docs.mka1.com/api-reference/feedback/list-chat-completion-feedback
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/feedback/completions
Retrieves a paginated list of feedback entries recorded on the caller's chat completions, ordered by the completion's creation date. Supports filtering by rating. An `after` cursor that no longer resolves to a completion visible to the caller returns 400; restart pagination from the first page.
# List response feedback
Source: https://docs.mka1.com/api-reference/feedback/list-response-feedback
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/feedback/responses
Retrieves a paginated list of feedback entries recorded on the caller's agent responses, ordered by the response's creation date. Supports filtering by rating. An `after` cursor that no longer resolves to a response visible to the caller — including responses that have since been deleted — returns 400; restart pagination from the first page.
# Retrieve feedback by completion ID
Source: https://docs.mka1.com/api-reference/feedback/retrieve-feedback-by-completion-id
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/feedback/completions/{id}
Retrieves the existing feedback rating and description for a specific chat completion.
# Retrieve feedback by response ID
Source: https://docs.mka1.com/api-reference/feedback/retrieve-feedback-by-response-id
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/feedback/responses/{id}
Retrieves the existing feedback rating and description for a specific agent response.
# Start feedback export
Source: https://docs.mka1.com/api-reference/feedback/start-feedback-export
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/feedback/export
Starts a background job to export all feedback data across every tenant to parquet files in S3/R2. Only one export can run simultaneously. Restricted to cluster administrators.
# Submit feedback for chat completion
Source: https://docs.mka1.com/api-reference/feedback/submit-feedback-for-chat-completion
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/feedback/completions
Submit user feedback for a specific chat completion to track satisfaction and model performance. Each completion can only receive feedback once.
# Submit feedback for response
Source: https://docs.mka1.com/api-reference/feedback/submit-feedback-for-response
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/feedback/responses
Submit user feedback for a specific agent response to track satisfaction and model performance. Each response can only receive feedback once.
# Update existing completion feedback
Source: https://docs.mka1.com/api-reference/feedback/update-existing-completion-feedback
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/feedback/completions/{id}
Updates or modifies existing feedback for a specific chat completion. Useful for allowing users to revise their initial submissions.
# Update existing response feedback
Source: https://docs.mka1.com/api-reference/feedback/update-existing-response-feedback
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/feedback/responses/{id}
Updates or modifies existing feedback for a specific agent response. Useful for allowing users to revise their initial submissions.
# Cancel Generation
Source: https://docs.mka1.com/api-reference/generations/cancel-generation
https://apigw.mka1.com/speakeasy.json post /api/v1/datasets/generations/{generation_id}/cancel
api.md §3: `cancelling` is written here, then the signal; a `cancelling` row whose
signal was lost (the retry case) is signalled again.
# Create Generation
Source: https://docs.mka1.com/api-reference/generations/create-generation
https://apigw.mka1.com/speakeasy.json post /api/v1/datasets/generations
The components.md §6 D.1 sequence, in its order: the run credential is minted before
anything is spent, nothing is written before the digest is pinned, and the workflow starts
only after the row is committed.
# Get Events
Source: https://docs.mka1.com/api-reference/generations/get-events
https://apigw.mka1.com/speakeasy.json get /api/v1/datasets/generations/{generation_id}/events
# Get Generation
Source: https://docs.mka1.com/api-reference/generations/get-generation
https://apigw.mka1.com/speakeasy.json get /api/v1/datasets/generations/{generation_id}
# Get Logs
Source: https://docs.mka1.com/api-reference/generations/get-logs
https://apigw.mka1.com/speakeasy.json get /api/v1/datasets/generations/{generation_id}/logs
# List Generations
Source: https://docs.mka1.com/api-reference/generations/list-generations
https://apigw.mka1.com/speakeasy.json get /api/v1/datasets/generations
# Get Generator
Source: https://docs.mka1.com/api-reference/generators/get-generator
https://apigw.mka1.com/speakeasy.json get /api/v1/datasets/generators/{generator_id}
# List Generators
Source: https://docs.mka1.com/api-reference/generators/list-generators
https://apigw.mka1.com/speakeasy.json get /api/v1/datasets/generators
# Quote Generator
Source: https://docs.mka1.com/api-reference/generators/quote-generator
https://apigw.mka1.com/speakeasy.json post /api/v1/datasets/generators/{generator_id}/quote
# Create a repository
Source: https://docs.mka1.com/api-reference/repositories/create-a-repository
https://apigw.mka1.com/speakeasy.json post /api/v1/repos
Provisions a repository (org owner/admin only); a failed provision is
rolled back best-effort (see the `502`). The repository belongs to the
caller's org. `kind` says what it will hold and defaults to `repo` (a
plain git repository); it decides which protocol planes answer for the
name (see the `Repo` schema).
# Delete a repository
Source: https://docs.mka1.com/api-reference/repositories/delete-a-repository
https://apigw.mka1.com/speakeasy.json delete /api/v1/repos/{org}/{name}
Removes a repository; org owner/admin only. The deletion is
authoritative; the contents are cleaned up best-effort.
# Delete an image tag
Source: https://docs.mka1.com/api-reference/repositories/delete-an-image-tag
https://apigw.mka1.com/speakeasy.json delete /api/v1/repos/{org}/{name}/tags/{tag}
Removes one tag; org owner/admin only (`write:repos` for a key). The
same untag as the registry's `DELETE /v2/{org}/{name}/manifests/{tag}`:
the name goes and the image stays, reachable by digest and by any
other tag that names it.
What makes a repository convertible afterwards is the kind switch
itself: `PATCH` to another `kind` first collects every image no tag
reaches (a multi-arch index's per-platform images included) and is
refused with `409 kind_has_content` only for images a tag still
names. So delete the tags the listing shows, then switch.
# Get a repository
Source: https://docs.mka1.com/api-reference/repositories/get-a-repository
https://apigw.mka1.com/speakeasy.json get /api/v1/repos/{org}/{name}
Reads a single repository after the org+role access check (org
owner/admin of the repository's org only).
# List an image repository's tags
Source: https://docs.mka1.com/api-reference/repositories/list-an-image-repositorys-tags
https://apigw.mka1.com/speakeasy.json get /api/v1/repos/{org}/{name}/tags
Lists the container-image tags a repository holds, newest-moved first,
each with the manifest it points at, the manifest's media type, the
image's declared size and when the tag last moved. The same access
check as reading the repository (org owner/admin; `read:repos` for a
key).
It is a fact about what the repository HOLDS, not about its `kind`:
a `model` lists `[]`, and a legacy `kind: null` repository that still
holds images lists them — those are the tags a `409 kind_has_content`
on PATCH is about, and deleting them through this API is what makes
that PATCH go through.
One page, of at most 1000 tags; `truncated` says whether the
repository holds more. The registry's own `GET /v2/{org}/{name}/tags/list`
is the paginated, names-only listing every OCI client speaks.
# List the caller's org's repositories
Source: https://docs.mka1.com/api-reference/repositories/list-the-callers-orgs-repositories
https://apigw.mka1.com/speakeasy.json get /api/v1/repos
Returns every repository in the caller's org (org owner/admin only).
Read-only. With `kind`, only repositories of that kind; an untyped
(legacy, `kind: null`) repository appears in the unfiltered listing
only.
# Update a repository's labels
Source: https://docs.mka1.com/api-reference/repositories/update-a-repositorys-labels
https://apigw.mka1.com/speakeasy.json patch /api/v1/repos/{org}/{name}
Applies a label-only update (name/description/kind); org owner/admin
only. The repository id is stable, so a rename touches no contents.
Omitted fields are left unchanged.
`kind` is the ONE way a repository's kind changes after creation (the
protocol planes never change it): it types a legacy `kind: null`
repository and corrects a wrong kind. `repo`, `model` and `dataset`
convert freely and any repository may become `image`; a repository
whose container images are still named by a tag can be given no
other kind — leaving `image`, or typing a legacy `null` repository as
anything else, is refused with `409 kind_has_content` (list and
delete the tags through this API first). A switch away from `image`
collects every image no tag reaches before it is judged, so an image
only ever pushed by digest, or untagged through the registry, never
blocks it. A kind is never un-set.
# Create
Source: https://docs.mka1.com/api-reference/tracking-experiments/create
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/experiments/create
Create a namespaced experiment. Artifact locations are managed by the service. Requires `write:tracking`. Results are restricted to the API key organization and team.
# Delete
Source: https://docs.mka1.com/api-reference/tracking-experiments/delete
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/experiments/delete
Requires `write:tracking`. Results are restricted to the API key organization and team.
# Get
Source: https://docs.mka1.com/api-reference/tracking-experiments/get
https://apigw.mka1.com/speakeasy.json get /api/2.0/mlflow/experiments/get
Requires `read:tracking`. Results are restricted to the API key organization and team.
# GetByName
Source: https://docs.mka1.com/api-reference/tracking-experiments/getbyname
https://apigw.mka1.com/speakeasy.json get /api/2.0/mlflow/experiments/get-by-name
Requires `read:tracking`. Results are restricted to the API key organization and team.
# Search
Source: https://docs.mka1.com/api-reference/tracking-experiments/search
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/experiments/search
Requires `read:tracking`. Results are restricted to the API key organization and team.
# Create
Source: https://docs.mka1.com/api-reference/tracking-runs/create
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/runs/create
Requires `write:tracking`. Results are restricted to the API key organization and team.
# Delete
Source: https://docs.mka1.com/api-reference/tracking-runs/delete
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/runs/delete
Requires `write:tracking`. Results are restricted to the API key organization and team.
# DeleteTag
Source: https://docs.mka1.com/api-reference/tracking-runs/deletetag
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/runs/delete-tag
Requires `write:tracking`. Results are restricted to the API key organization and team.
# Get
Source: https://docs.mka1.com/api-reference/tracking-runs/get
https://apigw.mka1.com/speakeasy.json get /api/2.0/mlflow/runs/get
Requires `read:tracking`. Results are restricted to the API key organization and team.
# GetMetricHistory
Source: https://docs.mka1.com/api-reference/tracking-runs/getmetrichistory
https://apigw.mka1.com/speakeasy.json get /api/2.0/mlflow/metrics/get-history
Requires `read:tracking`. Results are restricted to the API key organization and team.
# LogBatch
Source: https://docs.mka1.com/api-reference/tracking-runs/logbatch
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/2.0/mlflow/runs/log-batch
Requer `write:tracking`. Os resultados são restritos à organização e à equipe da chave de API.
# LogInputs
Source: https://docs.mka1.com/api-reference/tracking-runs/loginputs
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/2.0/mlflow/runs/log-inputs
Requer `write:tracking`. Os resultados são restritos à organização e à equipe da chave de API.
# LogMetric
Source: https://docs.mka1.com/api-reference/tracking-runs/logmetric
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/2.0/mlflow/runs/log-metric
Requer `write:tracking`. Os resultados são restritos à organização e à equipe da chave de API.
# LogParameter
Source: https://docs.mka1.com/api-reference/tracking-runs/logparameter
https://apigw.mka1.com/speakeasy.json?language=es post /api/2.0/mlflow/runs/log-parameter
Requiere `write:tracking`. Los resultados están restringidos a la organización y al equipo de la clave de API.
# Restore
Source: https://docs.mka1.com/api-reference/tracking-runs/restore
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/runs/restore
Requires `write:tracking`. Results are restricted to the API key organization and team.
# Search
Source: https://docs.mka1.com/api-reference/tracking-runs/search
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/runs/search
Explicit experiment IDs are required; every experiment must belong to the caller. Requires `read:tracking`. Results are restricted to the API key organization and team.
# SetTag
Source: https://docs.mka1.com/api-reference/tracking-runs/settag
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/runs/set-tag
Requires `write:tracking`. Results are restricted to the API key organization and team.
# Update
Source: https://docs.mka1.com/api-reference/tracking-runs/update
https://apigw.mka1.com/speakeasy.json post /api/2.0/mlflow/runs/update
Requires `write:tracking`. Results are restricted to the API key organization and team.
# Exchange API key for a JWT token
Source: https://docs.mka1.com/api-reference/api-key/exchange-api-key-for-a-jwt-token
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/api-key/exchange-token
Exchange an API key for a JWT token
# List scoped API keys
Source: https://docs.mka1.com/api-reference/api-key/list-scoped-api-keys
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/api-key/scoped
List the caller's scoped API keys (metadata only — never the secret). Optional `?orgId=&teamId=` narrows; a key caller is scoped to its own org.
# Mint a scoped API key
Source: https://docs.mka1.com/api-reference/api-key/mint-a-scoped-api-key
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/api-key/scoped
Mint an API key bound to a (principal, team) carrying an explicit scope set. Requires a session, or a bearer key holding `write:apikeys`. The plaintext secret is returned once.
# Rotate a scoped API key's secret
Source: https://docs.mka1.com/api-reference/api-key/rotate-a-scoped-api-keys-secret
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/api-key/scoped/regenerate
Issue a new plaintext secret for an existing key in place (id / scopes / binding preserved). Returned once.
# Update a scoped API key
Source: https://docs.mka1.com/api-reference/api-key/update-a-scoped-api-key
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/api-key/scoped/update
Update a key's scopes (and optionally name / rate limit). Scopes already on the key are retained; newly-added scopes are bounded by the caller's role (and, for a key caller, the calling key's own scopes).
# Delete a external user budget
Source: https://docs.mka1.com/api-reference/budgets/delete-a-external-user-budget
https://apigw.mka1.com/speakeasy.json delete /api/v1/budgeting/budgets/external-user/{id}
Removes the external user's budget for the given owner; the org's per-external user default budget (if any) applies to them again. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for external users in their own organization (owner=org).
# Delete a per-external user default budget
Source: https://docs.mka1.com/api-reference/budgets/delete-a-per-external-user-default-budget
https://apigw.mka1.com/speakeasy.json delete /api/v1/budgeting/budgets/external-user-default
Removes the org's per-external user default budget for the given owner; only explicit external user budgets remain. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# Delete a per-team default budget
Source: https://docs.mka1.com/api-reference/budgets/delete-a-per-team-default-budget
https://apigw.mka1.com/speakeasy.json delete /api/v1/budgeting/budgets/team-default
Removes the org's per-team default budget for the given owner; only explicit team budgets remain. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# Delete a per-user default budget
Source: https://docs.mka1.com/api-reference/budgets/delete-a-per-user-default-budget
https://apigw.mka1.com/speakeasy.json delete /api/v1/budgeting/budgets/user-default
Removes the org's per-user default budget for the given owner; only explicit user budgets remain. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# Delete a team budget
Source: https://docs.mka1.com/api-reference/budgets/delete-a-team-budget
https://apigw.mka1.com/speakeasy.json delete /api/v1/budgeting/budgets/team/{id}
Removes the team's budget for the given owner; the org's per-team default budget (if any) applies to them again. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for teams in their own organization (owner=org).
# Delete a user budget
Source: https://docs.mka1.com/api-reference/budgets/delete-a-user-budget
https://apigw.mka1.com/speakeasy.json delete /api/v1/budgeting/budgets/user/{id}
Removes the user's budget for the given owner; the org's per-user default budget (if any) applies to them again. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for users in their own organization (owner=org).
# Delete an apikey budget
Source: https://docs.mka1.com/api-reference/budgets/delete-an-apikey-budget
https://apigw.mka1.com/speakeasy.json delete /api/v1/budgeting/budgets/apikey/{apiKeyId}
Removes the apikey's budget for the given owner; enforcement and alerts stop. Callable by cluster admins, or org admins for API keys in their own organization.
# Delete an org budget
Source: https://docs.mka1.com/api-reference/budgets/delete-an-org-budget
https://apigw.mka1.com/speakeasy.json delete /api/v1/budgeting/budgets/org
Removes the org's budget for the given owner; enforcement and alerts stop. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only.
# List apikey budget events
Source: https://docs.mka1.com/api-reference/budgets/list-apikey-budget-events
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/apikey/{apiKeyId}/events
Returns recent threshold-alert and block events for the apikey's budgets. Callable by cluster admins, or org admins for API keys in their own organization.
# List apikey budgets
Source: https://docs.mka1.com/api-reference/budgets/list-apikey-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/apikey/{apiKeyId}
Returns the apikey's budgets (self-budget and/or ceiling) with each one's live spend gauge. Callable by cluster admins, or org admins for API keys in their own organization.
# List budgets
Source: https://docs.mka1.com/api-reference/budgets/list-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets
Cluster admins see all budgets; org admins see their org's budgets (including member budgets and per-member default budgets) plus budgets on API keys in their org.
# List external user budget events
Source: https://docs.mka1.com/api-reference/budgets/list-external-user-budget-events
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/external-user/{id}/events
Returns recent threshold-alert and block events for the external user's budgets in the target org. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for external users in their own organization (owner=org).
# List external user budgets
Source: https://docs.mka1.com/api-reference/budgets/list-external-user-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/external-user/{id}
Returns the external user's budgets in the target org (self-budget and/or ceiling) with each one's live spend gauge. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for external users in their own organization (owner=org).
# List org budget events
Source: https://docs.mka1.com/api-reference/budgets/list-org-budget-events
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/org/events
Returns recent threshold-alert and block events for the org's budgets. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only.
# List org budgets
Source: https://docs.mka1.com/api-reference/budgets/list-org-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/org
Returns the org's budgets (self-budget and/or ceiling) with each one's live spend gauge. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only.
# List per-external user default budget events
Source: https://docs.mka1.com/api-reference/budgets/list-per-external-user-default-budget-events
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/external-user-default/events
Returns recent threshold-alert and block events for the org's per-external user default budgets. Each event's target_id names the external user it fired for. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# List per-external user default budgets
Source: https://docs.mka1.com/api-reference/budgets/list-per-external-user-default-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/external-user-default
Returns the org's per-external user default budgets (self-set and/or operator ceiling). A default budget applies to every external user in the org against that external user's own spend counter, unless an explicit external user budget of the same owner and period exists for them. It has no spend gauge of its own. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# List per-team default budget events
Source: https://docs.mka1.com/api-reference/budgets/list-per-team-default-budget-events
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/team-default/events
Returns recent threshold-alert and block events for the org's per-team default budgets. Each event's target_id names the team it fired for. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# List per-team default budgets
Source: https://docs.mka1.com/api-reference/budgets/list-per-team-default-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/team-default
Returns the org's per-team default budgets (self-set and/or operator ceiling). A default budget applies to every team in the org against that team's own spend counter, unless an explicit team budget of the same owner and period exists for them. It has no spend gauge of its own. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# List per-user default budget events
Source: https://docs.mka1.com/api-reference/budgets/list-per-user-default-budget-events
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/user-default/events
Returns recent threshold-alert and block events for the org's per-user default budgets. Each event's target_id names the user it fired for. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# List per-user default budgets
Source: https://docs.mka1.com/api-reference/budgets/list-per-user-default-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/user-default
Returns the org's per-user default budgets (self-set and/or operator ceiling). A default budget applies to every user in the org against that user's own spend counter, unless an explicit user budget of the same owner and period exists for them. It has no spend gauge of its own. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# List team budget events
Source: https://docs.mka1.com/api-reference/budgets/list-team-budget-events
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/team/{id}/events
Returns recent threshold-alert and block events for the team's budgets in the target org. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for teams in their own organization (owner=org).
# List team budgets
Source: https://docs.mka1.com/api-reference/budgets/list-team-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/team/{id}
Returns the team's budgets in the target org (self-budget and/or ceiling) with each one's live spend gauge. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for teams in their own organization (owner=org).
# List user budget events
Source: https://docs.mka1.com/api-reference/budgets/list-user-budget-events
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/user/{id}/events
Returns recent threshold-alert and block events for the user's budgets in the target org. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for users in their own organization (owner=org).
# List user budgets
Source: https://docs.mka1.com/api-reference/budgets/list-user-budgets
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/budgets/user/{id}
Returns the user's budgets in the target org (self-budget and/or ceiling) with each one's live spend gauge. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for users in their own organization (owner=org).
# Set a external user budget
Source: https://docs.mka1.com/api-reference/budgets/set-a-external-user-budget
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/budgets/external-user/{id}
Creates or updates a budget for the external user in the target org. One budget per (scope, owner); editing re-evaluates against live spend. An explicit external user budget replaces the org's per-external user default budget of the same owner and period for this external user (exemption-by-override — it may raise or tighten it); different-period defaults, org budgets, and API-key budgets still apply. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for external users in their own organization (owner=org).
# Set a per-external user default budget
Source: https://docs.mka1.com/api-reference/budgets/set-a-per-external-user-default-budget
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/budgets/external-user-default
Creates or updates the org's per-external user default budget: a cap applying to EACH external user in the org individually (not in aggregate), unless an explicit external user budget of the same owner and period exists for them. Threshold alerts and blocks fire per external user. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# Set a per-team default budget
Source: https://docs.mka1.com/api-reference/budgets/set-a-per-team-default-budget
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/budgets/team-default
Creates or updates the org's per-team default budget: a cap applying to EACH team in the org individually (not in aggregate), unless an explicit team budget of the same owner and period exists for them. Threshold alerts and blocks fire per team. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# Set a per-user default budget
Source: https://docs.mka1.com/api-reference/budgets/set-a-per-user-default-budget
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/budgets/user-default
Creates or updates the org's per-user default budget: a cap applying to EACH user in the org individually (not in aggregate), unless an explicit user budget of the same owner and period exists for them. Threshold alerts and blocks fire per user. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for their own organization (owner=org).
# Set a team budget
Source: https://docs.mka1.com/api-reference/budgets/set-a-team-budget
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/budgets/team/{id}
Creates or updates a budget for the team in the target org. One budget per (scope, owner); editing re-evaluates against live spend. An explicit team budget replaces the org's per-team default budget of the same owner and period for this team (exemption-by-override — it may raise or tighten it); different-period defaults, org budgets, and API-key budgets still apply. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for teams in their own organization (owner=org).
# Set a user budget
Source: https://docs.mka1.com/api-reference/budgets/set-a-user-budget
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/budgets/user/{id}
Creates or updates a budget for the user in the target org. One budget per (scope, owner); editing re-evaluates against live spend. An explicit user budget replaces the org's per-user default budget of the same owner and period for this user (exemption-by-override — it may raise or tighten it); different-period defaults, org budgets, and API-key budgets still apply. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only. Callable by cluster admins, or org admins for users in their own organization (owner=org).
# Set an apikey budget
Source: https://docs.mka1.com/api-reference/budgets/set-an-apikey-budget
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/budgets/apikey/{apiKeyId}
Creates or updates a budget for the apikey. One budget per (scope, owner); editing re-evaluates against live spend. Callable by cluster admins, or org admins for API keys in their own organization.
# Set an org budget
Source: https://docs.mka1.com/api-reference/budgets/set-an-org-budget
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/budgets/org
Creates or updates a budget for the org. One budget per (scope, owner); editing re-evaluates against live spend. Targets the caller's own organization (inferred from the API key or session) unless the optional org_id query parameter names another org — cluster admins only.
# Accept a cluster invitation (public)
Source: https://docs.mka1.com/api-reference/cluster-admin/accept-a-cluster-invitation-public
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/cluster-invite/accept
Accept an invite and create the org. Existing signed-in user, new email/password owner, or (email-bound) headless machine owner with `passwordless: true, issueApiKey: true`. A reserved slug (`api`, whether supplied as `orgSlug` or derived from `orgName`) is refused with 400 `reserved_org_slug`; a slug another org already holds is refused with 409. Note `POST /organization/check-slug` does not know about reserved slugs and will report `api` as available.
# Create a cluster invitation
Source: https://docs.mka1.com/api-reference/cluster-admin/create-a-cluster-invitation
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/admin/cluster/invitations
Issue a one-shot invite that provisions a new org on acceptance. Email-bound invites can be accepted headless (passwordless + issueApiKey).
# Get an organization
Source: https://docs.mka1.com/api-reference/cluster-admin/get-an-organization
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/admin/cluster/orgs/{id}
# Invite members on behalf of an organization
Source: https://docs.mka1.com/api-reference/cluster-admin/invite-members-on-behalf-of-an-organization
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/admin/cluster/orgs/{id}/invitations
Requires a cluster-admin session with Cluster as its active organization. The target must be active and cannot be Cluster. Sends up to 20 organization invitations without switching the admin's session or joining the target organization. Each row accepts role member or admin, defaulting to member; owner and custom roles are not supported. New invitations include the target's oldest team when one exists. Results follow input order; invalid emails, duplicates, existing members, pending invitations, and delivery failures are reported per row. An existing pending invitation must match the requested role, including when resend is false. An explicit resend reuses a matching pending invitation with no team or the target's oldest team, preserving its inviter, role, and team. Invitation expiry is 48 hours; at most 100 unexpired pending invitations are allowed per organization. API keys are not supported.
# List all organizations
Source: https://docs.mka1.com/api-reference/cluster-admin/list-all-organizations
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/admin/cluster/orgs
# List cluster invitations
Source: https://docs.mka1.com/api-reference/cluster-admin/list-cluster-invitations
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/admin/cluster/invitations
# Re-issue an org owner key (recovery)
Source: https://docs.mka1.com/api-reference/cluster-admin/re-issue-an-org-owner-key-recovery
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/admin/cluster/orgs/{id}/owner-key
Mint a fresh owner-bound key for an org whose credential was lost. Cluster-admin only (`write:cluster`). Defaults to the org's oldest human owner and oldest team; `userId` / `teamId` override.
# Read cluster-invite info (public)
Source: https://docs.mka1.com/api-reference/cluster-admin/read-cluster-invite-info-public
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/cluster-invite/info
# Revoke a cluster invitation
Source: https://docs.mka1.com/api-reference/cluster-admin/revoke-a-cluster-invitation
https://apigw.mka1.com/speakeasy.json delete /api/v1/authentication/admin/cluster/invitations/{id}
# Soft-delete an organization
Source: https://docs.mka1.com/api-reference/cluster-admin/soft-delete-an-organization
https://apigw.mka1.com/speakeasy.json delete /api/v1/authentication/admin/cluster/orgs/{id}
# Suspend an organization
Source: https://docs.mka1.com/api-reference/cluster-admin/suspend-an-organization
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/admin/cluster/orgs/{id}/suspend
# Unsuspend an organization
Source: https://docs.mka1.com/api-reference/cluster-admin/unsuspend-an-organization
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/admin/cluster/orgs/{id}/unsuspend
# Update a pending cluster invitation
Source: https://docs.mka1.com/api-reference/cluster-admin/update-a-pending-cluster-invitation
https://apigw.mka1.com/speakeasy.json patch /api/v1/authentication/admin/cluster/invitations/{id}
Extend the expiry or atomically replace the available-model, API-quota, or compute policy of an unclaimed, unexpired invitation. Omitted top-level fields are preserved.
# Get Format
Source: https://docs.mka1.com/api-reference/formats/get-format
https://apigw.mka1.com/speakeasy.json get /api/v1/datasets/formats/{format_id}
# List Formats
Source: https://docs.mka1.com/api-reference/formats/list-formats
https://apigw.mka1.com/speakeasy.json get /api/v1/datasets/formats
# Add a team member
Source: https://docs.mka1.com/api-reference/organization/add-a-team-member
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/orgs/{orgId}/teams/{teamId}/members
Attach a principal (user or service account) to the team by its userId.
# Create a service account
Source: https://docs.mka1.com/api-reference/organization/create-a-service-account
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/orgs/{orgId}/service-accounts
Mint a non-human principal scoped to this org (org owner/admin only).
# Create a team
Source: https://docs.mka1.com/api-reference/organization/create-a-team
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/orgs/{orgId}/teams
# Delete a service account
Source: https://docs.mka1.com/api-reference/organization/delete-a-service-account
https://apigw.mka1.com/speakeasy.json delete /api/v1/authentication/orgs/{orgId}/service-accounts/{saId}
# Delete a service-account API key
Source: https://docs.mka1.com/api-reference/organization/delete-a-service-account-api-key
https://apigw.mka1.com/speakeasy.json delete /api/v1/authentication/orgs/{orgId}/service-accounts/{saId}/api-keys/{keyId}
# Delete a team
Source: https://docs.mka1.com/api-reference/organization/delete-a-team
https://apigw.mka1.com/speakeasy.json delete /api/v1/authentication/orgs/{orgId}/teams/{teamId}
# Get a service account
Source: https://docs.mka1.com/api-reference/organization/get-a-service-account
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}/service-accounts/{saId}
# Get a team
Source: https://docs.mka1.com/api-reference/organization/get-a-team
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}/teams/{teamId}
# Get an org's rate limit
Source: https://docs.mka1.com/api-reference/organization/get-an-orgs-rate-limit
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}/rate-limit
# Get an org's usage quota
Source: https://docs.mka1.com/api-reference/organization/get-an-orgs-usage-quota
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}/quota
# Get basic organization details
Source: https://docs.mka1.com/api-reference/organization/get-basic-organization-details
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}
Returns basic fields and the full metadata object to a member of the organization or a cluster admin. It never includes member identities, invitations, or API-key details.
# List a service account's API keys
Source: https://docs.mka1.com/api-reference/organization/list-a-service-accounts-api-keys
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}/service-accounts/{saId}/api-keys
# List service accounts
Source: https://docs.mka1.com/api-reference/organization/list-service-accounts
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}/service-accounts
# List team members
Source: https://docs.mka1.com/api-reference/organization/list-team-members
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}/teams/{teamId}/members
# List teams in an org
Source: https://docs.mka1.com/api-reference/organization/list-teams-in-an-org
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/orgs/{orgId}/teams
# Patch organization metadata (cluster-admin)
Source: https://docs.mka1.com/api-reference/organization/patch-organization-metadata-cluster-admin
https://apigw.mka1.com/speakeasy.json patch /api/v1/authentication/orgs/{orgId}
Merges supplied top-level metadata keys while preserving omitted siblings. metadata.codeConfig accepts one releaseManifestUrl; codeConfig:null removes that override.
# Remove a team member
Source: https://docs.mka1.com/api-reference/organization/remove-a-team-member
https://apigw.mka1.com/speakeasy.json delete /api/v1/authentication/orgs/{orgId}/teams/{teamId}/members/{memberId}
# Rename a team
Source: https://docs.mka1.com/api-reference/organization/rename-a-team
https://apigw.mka1.com/speakeasy.json patch /api/v1/authentication/orgs/{orgId}/teams/{teamId}
# Rotate a service-account API key's secret
Source: https://docs.mka1.com/api-reference/organization/rotate-a-service-account-api-keys-secret
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/orgs/{orgId}/service-accounts/{saId}/api-keys/{keyId}/regenerate
# Set an org's rate limit (cluster-admin)
Source: https://docs.mka1.com/api-reference/organization/set-an-orgs-rate-limit-cluster-admin
https://apigw.mka1.com/speakeasy.json patch /api/v1/authentication/orgs/{orgId}/rate-limit
# Set an org's usage quota (cluster-admin)
Source: https://docs.mka1.com/api-reference/organization/set-an-orgs-usage-quota-cluster-admin
https://apigw.mka1.com/speakeasy.json patch /api/v1/authentication/orgs/{orgId}/quota
# Update a service-account API key
Source: https://docs.mka1.com/api-reference/organization/update-a-service-account-api-key
https://apigw.mka1.com/speakeasy.json patch /api/v1/authentication/orgs/{orgId}/service-accounts/{saId}/api-keys/{keyId}
# Check an explicit subject permission
Source: https://docs.mka1.com/api-reference/resource-authorization/check-an-explicit-subject-permission
https://apigw.mka1.com/speakeasy.json post /api/v1/authorization/git/check
Check whether a specific subject (given in the body) has a role on a git resource. Used by the authorization proxy to enforce access for the git user it is acting on behalf of. The authenticated caller must carry the read authorization scope; the subject is independent of the caller.
# Check user permission
Source: https://docs.mka1.com/api-reference/resource-authorization/check-user-permission
https://apigw.mka1.com/speakeasy.json get /api/v1/authorization/llm/check
Check whether the authenticated caller has a specific role on a resource.
# Create a new git resource
Source: https://docs.mka1.com/api-reference/resource-authorization/create-a-new-git-resource
https://apigw.mka1.com/speakeasy.json post /api/v1/authorization/git/create
Create a git resource and assign the authenticated caller as owner. Existing owners may pass overwrite=true to replace direct relationships for the resource.
# Create a new resource
Source: https://docs.mka1.com/api-reference/resource-authorization/create-a-new-resource
https://apigw.mka1.com/speakeasy.json post /api/v1/authorization/llm/create
Create an LLM resource and assign the authenticated caller as owner. Existing owners may pass overwrite=true to replace direct relationships for the resource.
# Delete a git resource
Source: https://docs.mka1.com/api-reference/resource-authorization/delete-a-git-resource
https://apigw.mka1.com/speakeasy.json delete /api/v1/authorization/git/delete
Delete a git resource and all of its direct permissions. Only owners can delete resources.
# Delete a resource
Source: https://docs.mka1.com/api-reference/resource-authorization/delete-a-resource
https://apigw.mka1.com/speakeasy.json delete /api/v1/authorization/llm/delete
Delete an LLM resource and all of its direct permissions. Only owners can delete resources.
# Grant permission to a user or make public
Source: https://docs.mka1.com/api-reference/resource-authorization/grant-permission-to-a-user-or-make-public
https://apigw.mka1.com/speakeasy.json post /api/v1/authorization/git/grant
Grant a role to a user for a git resource, or grant public access by using "*" as userId. Only owners can grant permissions. Public access is allowed only for writer and reader roles.
# List resources the user has access to
Source: https://docs.mka1.com/api-reference/resource-authorization/list-resources-the-user-has-access-to
https://apigw.mka1.com/speakeasy.json get /api/v1/authorization/llm/list
List resources of a specific type where the authenticated caller has the specified role. Returns direct relationships only (not computed).
# List users with permissions
Source: https://docs.mka1.com/api-reference/resource-authorization/list-users-with-permissions
https://apigw.mka1.com/speakeasy.json get /api/v1/authorization/llm/list-users
List users with a specific role on a resource. Returns direct relationships only (not computed). The authenticated caller must have at least reader access.
# Revoke permission from a user or remove public access
Source: https://docs.mka1.com/api-reference/resource-authorization/revoke-permission-from-a-user-or-remove-public-access
https://apigw.mka1.com/speakeasy.json post /api/v1/authorization/git/revoke
Revoke a role from a user for a git resource, or remove public access by using "*" as userId. Only owners can revoke permissions.
# Exchange a live session for a delegated access token
Source: https://docs.mka1.com/api-reference/session/exchange-a-live-session-for-a-delegated-access-token
https://apigw.mka1.com/speakeasy.json post /api/v1/authentication/session/exchange-token
Mints a short-lived, audience-bound token with the same authority as the current live browser or device-login session. Identity, tenancy, permissions, and lifetime cannot be selected by the caller. The JSON body is limited to 4 KiB.
# Find an unfinished invitation for the signed-in recipient
Source: https://docs.mka1.com/api-reference/session/find-an-unfinished-invitation-for-the-signed-in-recipient
https://apigw.mka1.com/speakeasy.json get /api/v1/authentication/pending-invitation
Requires a session with a verified email. Returns a pending, unexpired organization invitation first, otherwise an unclaimed, unexpired cluster invitation bound to that email. Open cluster invitations are never returned. Does not accept or modify the invitation.
# Aggregate cost by dimension
Source: https://docs.mka1.com/api-reference/usage/aggregate-cost-by-dimension
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/usage/costs
Sums stored per-entry cost over [start_time, end_time), grouped by any of service, task_type, model, api_key_id, team_id, user_id, external_user_id, org_id. Point-in-time correct for chargeback/showback.
# Get classify usage
Source: https://docs.mka1.com/api-reference/usage/get-classify-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/classify
Retrieve usage metrics for classify operations.
# Get completions usage
Source: https://docs.mka1.com/api-reference/usage/get-completions-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/completions
Retrieve usage metrics for chat completions, aggregated from the ChatCompletion table.
# Get conversations usage
Source: https://docs.mka1.com/api-reference/usage/get-conversations-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/conversations
Retrieve usage metrics for conversation operations.
# Get cost by model
Source: https://docs.mka1.com/api-reference/usage/get-cost-by-model
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/costs
Aggregates spend by model over a time range, priced in the cluster currency from the model price book. Org-scoped: org admins see their org; cluster admins may pass `org_id`. Includes billable work with no usage row of its own (store=false responses, agent tool calls), so totals cover all LLM spend. Platform-wide, cross-service cost reporting lives in the budgeting API (/api/v1/budgeting/usage/costs).
# Get embeddings usage
Source: https://docs.mka1.com/api-reference/usage/get-embeddings-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/embeddings
Retrieve usage metrics for embedding operations.
# Get extract usage
Source: https://docs.mka1.com/api-reference/usage/get-extract-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/extract
Retrieve usage metrics for extract operations.
# Get files usage
Source: https://docs.mka1.com/api-reference/usage/get-files-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/files
Retrieve bytes of files created per period from durable file creation events. This does not reflect current retained storage, buckets remain counted after file deletion, and grouped results collapse by requested output dimensions rather than one row per UserContext.
# Get responses usage
Source: https://docs.mka1.com/api-reference/usage/get-responses-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/responses
Retrieve usage metrics for agent responses, aggregated from the Response table.
# Get vector stores usage
Source: https://docs.mka1.com/api-reference/usage/get-vector-stores-usage
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/usage/vector_stores
Retrieve usage metrics for vector storage operations.
# Capture events
Source: https://docs.mka1.com/api-reference/analytics/durably-accept-a-batch-of-events
https://apigw.mka1.com/speakeasy.json post /api/v1/analytics/capture
Send a batch of events using the project's X-Analytics-Key header. A 202 response confirms the batch is stored; events become available to queries after background processing. Retry with the same idempotency_key and unchanged events if you do not receive a response.
# Query events
Source: https://docs.mka1.com/api-reference/analytics/query-event-counts-or-unique-visitors
https://apigw.mka1.com/speakeasy.json post /api/v1/analytics/projects/{id}/query
Count events or unique visitors in a time range. Optionally filter by event name or properties, group by one property, and split results into hour, day, or week buckets that start on the clock of an IANA time zone, UTC by default. Each bucket is returned as the UTC instant at which it starts. The range includes from and excludes to. Duplicate event IDs are counted once. An unknown time zone returns 400.
# Search events
Source: https://docs.mka1.com/api-reference/analyticsevents/search-events-in-a-time-range
https://apigw.mka1.com/speakeasy.json post /api/v1/analytics/projects/{id}/events/search
List individual events in a time range, newest first, with their properties. Optionally filter by event name, event properties, or one visitor's distinct_id. The range includes from and excludes to, and duplicate event IDs are returned once, so a search over a chart bucket's range with the same filters lists exactly the events that bucket counted. A page holds up to 100 events; pass next_cursor as cursor for the following page until it is null. The first page takes a snapshot from ClickHouse's clock before reading its rows and its cursor carries it, so every page of the sequence, the first included, reads only deliveries received at or before that snapshot and ages events out of retention as of it: no event repeats or is skipped, and events received after the snapshot, including a redelivery that revises a listed event, appear only when paging restarts without a cursor. One window blurs that boundary: ClickHouse stamps a receipt at whole seconds when an insert starts and commits its rows when it finishes, so a delivery stamped in or before the snapshot's second that commits after the first page was read is inside the sequence but missing from the first page; it joins from the next page, where an unlisted event it adds or moves ahead of the cursor is skipped and a listed event that a lower-hash redelivery moves behind the cursor repeats at its revised position. A cursor that does not decode, or one from another list, returns 400. A page whose events exceed the response size limit returns 413; request a smaller limit.
# Create a capture key
Source: https://docs.mka1.com/api-reference/analyticskeys/create-a-capture-key-and-return-its-secret-once
https://apigw.mka1.com/speakeasy.json post /api/v1/analytics/projects/{id}/keys
Create a key that can send events to this project. Save the key from this response; its secret is only returned once. Capture keys cannot read analytics or manage projects.
# List capture keys
Source: https://docs.mka1.com/api-reference/analyticskeys/list-capture-key-metadata
https://apigw.mka1.com/speakeasy.json get /api/v1/analytics/projects/{id}/keys
# Revoke a capture key
Source: https://docs.mka1.com/api-reference/analyticskeys/revoke-a-capture-key
https://apigw.mka1.com/speakeasy.json delete /api/v1/analytics/projects/{id}/keys/{keyId}
# Archive a project
Source: https://docs.mka1.com/api-reference/analyticsprojects/archive-an-analytics-project
https://apigw.mka1.com/speakeasy.json delete /api/v1/analytics/projects/{id}
Stop new captures and queries for this project. Previously accepted events continue processing. Archiving does not delete stored events.
# Create a project
Source: https://docs.mka1.com/api-reference/analyticsprojects/create-an-analytics-project
https://apigw.mka1.com/speakeasy.json post /api/v1/analytics/projects
Create a project in the caller's organization. Without team_id the project belongs to the authenticated team. Organization owners and admins can create a project for any team in their organization, including teams they are not a member of, or pass team_id: null for an organization-level project. Service accounts can only create projects for their own team; any other team_id returns 403. team_id is trimmed. Ownership cannot be changed after creation.
# Get a project
Source: https://docs.mka1.com/api-reference/analyticsprojects/get-an-analytics-project
https://apigw.mka1.com/speakeasy.json get /api/v1/analytics/projects/{id}
# List projects
Source: https://docs.mka1.com/api-reference/analyticsprojects/list-accessible-analytics-projects
https://apigw.mka1.com/speakeasy.json get /api/v1/analytics/projects
Organization owners and admins see every project in their organization: all teams' projects and organization-level projects, regardless of their active team. This also applies to an owner's or admin's API keys and exchanged JWTs, whichever team the key was issued for; use a service account for a team-confined credential. Service accounts see only their own team's projects. team_id and ownership narrow that set and never widen it, so filtering by a team the caller cannot access returns an empty list. ownership=organization combined with team_id returns 400. Unknown or repeated query parameters also return 400.
# Update a project
Source: https://docs.mka1.com/api-reference/analyticsprojects/rename-an-active-analytics-project
https://apigw.mka1.com/speakeasy.json patch /api/v1/analytics/projects/{id}
Rename an active project. Project ownership cannot be changed.
# Search visitors
Source: https://docs.mka1.com/api-reference/analyticsvisitors/search-visitors-in-a-time-range
https://apigw.mka1.com/speakeasy.json post /api/v1/analytics/projects/{id}/visitors/search
List visitors with matching events in a time range, most recently active first. Each visitor is one distinct_id with the timestamps of its first and last matching event and its event count over the whole range, so for a range that receives no further events the number of visitors across all pages equals the unique_visitors query for the same range and filters. The range includes from and excludes to, and duplicate event IDs are counted once. A page holds up to 100 visitors; pass next_cursor as cursor for the following page until it is null. The first page takes a snapshot from ClickHouse's clock before reading its rows and its cursor carries it, so every page of the sequence, the first included, reads only deliveries received at or before that snapshot and ages events out of retention as of it: a visitor keeps the position, first_seen, last_seen and event_count the sequence started with, no visitor repeats or is skipped, and activity received after the snapshot appears only when paging restarts without a cursor. One window blurs that boundary: ClickHouse stamps a receipt at whole seconds when an insert starts and commits its rows when it finishes, so a delivery stamped in or before the snapshot's second that commits after the first page was read is inside the sequence but missing from the first page; it joins from the next page, where an unlisted visitor it adds or moves ahead of the cursor is skipped and a listed visitor whose winning delivery a lower-hash redelivery moves behind the cursor repeats with revised totals; a listed visitor's totals otherwise stay as listed. A cursor that does not decode, or one from another list, returns 400.
# Cancel a batch
Source: https://docs.mka1.com/api-reference/batches/cancel-a-batch
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/batches/{batch_id}/cancel
Cancels an in-progress batch. The batch status changes to cancelling, and remaining requests will not be processed.
# Create a batch
Source: https://docs.mka1.com/api-reference/batches/create-a-batch
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/batches
Creates and executes a batch from an uploaded JSONL file of requests. Each line must have custom_id, method, url, and body fields. Text batches also require write:responses.
# Get a batch
Source: https://docs.mka1.com/api-reference/batches/get-a-batch
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/batches/{batch_id}
Retrieves a batch by its ID.
# List batches
Source: https://docs.mka1.com/api-reference/batches/list-batches
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/batches
Returns a paginated list of batches owned by the authenticated user.
# Get apiv1budgetingbillingorg
Source: https://docs.mka1.com/api-reference/billing/get-apiv1budgetingbillingorg
https://apigw.mka1.com/speakeasy.json?language=pt-BR get /api/v1/budgeting/billing/org
# Get apiv1budgetingbillingorginvoices
Source: https://docs.mka1.com/api-reference/billing/get-apiv1budgetingbillingorginvoices
https://apigw.mka1.com/speakeasy.json?language=pt-BR get /api/v1/budgeting/billing/org/invoices
# Post apiv1budgetingbillingorgportal session
Source: https://docs.mka1.com/api-reference/billing/post-apiv1budgetingbillingorgportal-session
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/v1/budgeting/billing/org/portal-session
# Post apiv1budgetingbillingorgsetup session
Source: https://docs.mka1.com/api-reference/billing/post-apiv1budgetingbillingorgsetup-session
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/v1/budgeting/billing/org/setup-session
# Put apiv1budgetingbillingorgenabled
Source: https://docs.mka1.com/api-reference/billing/put-apiv1budgetingbillingorgenabled
https://apigw.mka1.com/speakeasy.json?language=pt-BR put /api/v1/budgeting/billing/org/enabled
# Put apiv1budgetingbillingorgprofile
Source: https://docs.mka1.com/api-reference/billing/put-apiv1budgetingbillingorgprofile
https://apigw.mka1.com/speakeasy.json?language=pt-BR put /api/v1/budgeting/billing/org/profile
# [Deprecated] Chat completions for OpenAI SDK/client usage
Source: https://docs.mka1.com/api-reference/chat-completions/[deprecated]-chat-completions-for-openai-sdkclient-usage
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/chat/completions
**Deprecated: Use the Responses API (`/api/v1/llm/responses`) instead.** OpenAI-compatible chat completion endpoint designed for use with the official OpenAI client libraries (Python, Node.js, etc.). Supports both streaming and non-streaming requests by setting the `stream` parameter. This endpoint handles the request/response directly and returns standard OpenAI-formatted responses. Use this when integrating with existing OpenAI client code. Note: The actual handler is registered at the Bun server level for optimal performance with the OpenAI SDK streaming format.
# [Deprecated] Streaming chat completions for generated SDK usage
Source: https://docs.mka1.com/api-reference/chat-completions/[deprecated]-streaming-chat-completions-for-generated-sdk-usage
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/chat/completions/stream
**Deprecated: Use the Responses API (`/api/v1/llm/responses`) instead.** Streaming chat completion endpoint designed for use with the generated TypeScript/JavaScript SDK from the OpenAPI specification. This endpoint uses ORPC's native streaming via async generators and returns Server-Sent Events (SSE) formatted as structured JSON chunks. Unlike the OpenAI client endpoint, this provides better type safety and integration with the generated SDK. Use this endpoint when working with the auto-generated API client for type-safe streaming responses. The endpoint supports response caching, request resumption via `x-last-chunk-index` header, and automatic usage tracking.
# Create reusable extraction schema template
Source: https://docs.mka1.com/api-reference/extract/create-reusable-extraction-schema-template
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/extract/schema
Creates and stores a reusable JSON Schema template for structured data extraction.
# Delete extraction schema by ID
Source: https://docs.mka1.com/api-reference/extract/delete-extraction-schema-by-id
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/extract/schema/{schema_id}
Remove a stored extraction schema.
# Extract data using saved schema template
Source: https://docs.mka1.com/api-reference/extract/extract-data-using-saved-schema-template
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/extract/schema/{schema_id}
Extracts structured data from files using a previously saved extraction schema template.
# Extract structured data with inline JSON Schema
Source: https://docs.mka1.com/api-reference/extract/extract-structured-data-with-inline-json-schema
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/extract
Extracts structured data from files using a custom inline JSON schema.
# Get extraction schema by ID
Source: https://docs.mka1.com/api-reference/extract/get-extraction-schema-by-id
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/extract/schema/{schema_id}
Retrieve a stored extraction schema and its metadata.
# Update extraction schema by ID
Source: https://docs.mka1.com/api-reference/extract/update-extraction-schema-by-id
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/extract/schema/{schema_id}
Update an existing extraction schema and its metadata.
# Archive a flag
Source: https://docs.mka1.com/api-reference/feature-flags/archive-a-flag
https://apigw.mka1.com/speakeasy.json post /api/v1/flags/{key}/archive
Archived flags are excluded from evaluation in every environment; their settings are kept.
# Create a flag
Source: https://docs.mka1.com/api-reference/feature-flags/create-a-flag
https://apigw.mka1.com/speakeasy.json post /api/v1/flags
The flag starts disabled in every environment and belongs to Default when project_id is omitted.
# Create a project
Source: https://docs.mka1.com/api-reference/feature-flags/create-a-project
https://apigw.mka1.com/speakeasy.json post /api/v1/flags/-/projects
# Create an environment
Source: https://docs.mka1.com/api-reference/feature-flags/create-an-environment
https://apigw.mka1.com/speakeasy.json post /api/v1/flags/environments
Every existing flag gets a disabled state in the new environment.
# Delete a flag and its settings in every environment
Source: https://docs.mka1.com/api-reference/feature-flags/delete-a-flag-and-its-settings-in-every-environment
https://apigw.mka1.com/speakeasy.json delete /api/v1/flags/{key}
# Delete an empty project
Source: https://docs.mka1.com/api-reference/feature-flags/delete-an-empty-project
https://apigw.mka1.com/speakeasy.json delete /api/v1/flags/-/projects/{project}
Default cannot be deleted. Move or delete every flag before deleting another project.
# Delete an environment and every flag setting in it
Source: https://docs.mka1.com/api-reference/feature-flags/delete-an-environment-and-every-flag-setting-in-it
https://apigw.mka1.com/speakeasy.json delete /api/v1/flags/environments/{env}
# Evaluate every flag for an identity
Source: https://docs.mka1.com/api-reference/feature-flags/evaluate-every-flag-for-an-identity
https://apigw.mka1.com/speakeasy.json get /api/v1/flags/environments/{env}/evaluate
Resolves every non-archived flag of the environment for an anonymous caller, or for the identity given in the query. Sends an ETag and answers 304 to a matching If-None-Match after authenticating the environment evaluation key.
# Evaluate every flag for an identity with traits
Source: https://docs.mka1.com/api-reference/feature-flags/evaluate-every-flag-for-an-identity-with-traits
https://apigw.mka1.com/speakeasy.json post /api/v1/flags/environments/{env}/evaluate
# Generate or replace an environment evaluation key
Source: https://docs.mka1.com/api-reference/feature-flags/generate-or-replace-an-environment-evaluation-key
https://apigw.mka1.com/speakeasy.json post /api/v1/flags/environments/{env}/evaluation-key
Returns the new plaintext key once. Only its SHA-256 digest and a display hint are stored; generating another key immediately replaces the previous credential on this replica.
# Get a flag
Source: https://docs.mka1.com/api-reference/feature-flags/get-a-flag
https://apigw.mka1.com/speakeasy.json get /api/v1/flags/{key}
# Get a project
Source: https://docs.mka1.com/api-reference/feature-flags/get-a-project
https://apigw.mka1.com/speakeasy.json get /api/v1/flags/-/projects/{project}
# List audit entries, newest first
Source: https://docs.mka1.com/api-reference/feature-flags/list-audit-entries-newest-first
https://apigw.mka1.com/speakeasy.json get /api/v1/flags/audit
# List environments
Source: https://docs.mka1.com/api-reference/feature-flags/list-environments
https://apigw.mka1.com/speakeasy.json get /api/v1/flags/environments
# List flags
Source: https://docs.mka1.com/api-reference/feature-flags/list-flags
https://apigw.mka1.com/speakeasy.json get /api/v1/flags
Every flag with a per-environment digest of its state.
# List projects
Source: https://docs.mka1.com/api-reference/feature-flags/list-projects
https://apigw.mka1.com/speakeasy.json get /api/v1/flags/-/projects
# Rename a project
Source: https://docs.mka1.com/api-reference/feature-flags/rename-a-project
https://apigw.mka1.com/speakeasy.json patch /api/v1/flags/-/projects/{project}
# Rename an environment
Source: https://docs.mka1.com/api-reference/feature-flags/rename-an-environment
https://apigw.mka1.com/speakeasy.json patch /api/v1/flags/environments/{env}
# Replace a flag's settings in one environment
Source: https://docs.mka1.com/api-reference/feature-flags/replace-a-flags-settings-in-one-environment
https://apigw.mka1.com/speakeasy.json put /api/v1/flags/{key}/environments/{env}
# Restore an archived flag
Source: https://docs.mka1.com/api-reference/feature-flags/restore-an-archived-flag
https://apigw.mka1.com/speakeasy.json post /api/v1/flags/{key}/unarchive
# Revoke an environment evaluation key
Source: https://docs.mka1.com/api-reference/feature-flags/revoke-an-environment-evaluation-key
https://apigw.mka1.com/speakeasy.json delete /api/v1/flags/environments/{env}/evaluation-key
Revocation is idempotent while the environment exists.
# Update a flag's name, description, default value, or project
Source: https://docs.mka1.com/api-reference/feature-flags/update-a-flags-name-description-default-value-or-project
https://apigw.mka1.com/speakeasy.json patch /api/v1/flags/{key}
# [Deprecated] Cancel a fine-tuning job
Source: https://docs.mka1.com/api-reference/fine-tuning/[deprecated]-cancel-a-fine-tuning-job
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/fine_tuning/jobs/{fine_tuning_job_id}/cancel
**Deprecated: Use Compute jobs (`/api/v1/compute/jobs`) instead.** Immediately cancel a fine-tuning job.
# [Deprecated] Create a fine-tuning job
Source: https://docs.mka1.com/api-reference/fine-tuning/[deprecated]-create-a-fine-tuning-job
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/fine_tuning/jobs
**Deprecated: Use Compute jobs (`/api/v1/compute/jobs`) instead.** Creates a fine-tuning job which begins the process of training a new model from a given dataset.
# [Deprecated] List fine-tuning checkpoints
Source: https://docs.mka1.com/api-reference/fine-tuning/[deprecated]-list-fine-tuning-checkpoints
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/fine_tuning/jobs/{fine_tuning_job_id}/checkpoints
**Deprecated: Use Compute jobs (`/api/v1/compute/jobs`) instead.** List checkpoints for a fine-tuning job.
# [Deprecated] List fine-tuning events
Source: https://docs.mka1.com/api-reference/fine-tuning/[deprecated]-list-fine-tuning-events
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/fine_tuning/jobs/{fine_tuning_job_id}/events
**Deprecated: Use Compute jobs (`/api/v1/compute/jobs`) instead.** Get status updates for a fine-tuning job.
# [Deprecated] List fine-tuning jobs
Source: https://docs.mka1.com/api-reference/fine-tuning/[deprecated]-list-fine-tuning-jobs
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/fine_tuning/jobs
**Deprecated: Use Compute jobs (`/api/v1/compute/jobs`) instead.** List your organization's fine-tuning jobs.
# [Deprecated] Pause a fine-tuning job
Source: https://docs.mka1.com/api-reference/fine-tuning/[deprecated]-pause-a-fine-tuning-job
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/fine_tuning/jobs/{fine_tuning_job_id}/pause
**Deprecated: Use Compute jobs (`/api/v1/compute/jobs`) instead.** Pause a running fine-tuning job.
# [Deprecated] Resume a fine-tuning job
Source: https://docs.mka1.com/api-reference/fine-tuning/[deprecated]-resume-a-fine-tuning-job
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/fine_tuning/jobs/{fine_tuning_job_id}/resume
**Deprecated: Use Compute jobs (`/api/v1/compute/jobs`) instead.** Resume a paused fine-tuning job.
# [Deprecated] Retrieve a fine-tuning job
Source: https://docs.mka1.com/api-reference/fine-tuning/[deprecated]-retrieve-a-fine-tuning-job
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/fine_tuning/jobs/{fine_tuning_job_id}
**Deprecated: Use Compute jobs (`/api/v1/compute/jobs`) instead.** Get info about a fine-tuning job.
# Delete guardrails policy
Source: https://docs.mka1.com/api-reference/guardrails/delete-guardrails-policy
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/guardrails
Delete a guardrails policy. Omit team_id to delete the org-wide policy (org admin only); provide team_id to delete that team's policy (org admins may target any team in their org, other callers only their own team). Idempotent: deleting a policy that doesn't exist returns deleted: false.
# Get effective guardrails
Source: https://docs.mka1.com/api-reference/guardrails/get-effective-guardrails
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/guardrails
Retrieve the guardrails that apply to the caller's requests: the org-wide policy plus the caller's team policy, combined. Both are enforced when both exist. Policies are managed by org admins via PUT /guardrails.
# List guardrails policies
Source: https://docs.mka1.com/api-reference/guardrails/list-guardrails-policies
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/guardrails/policies
List the stored guardrails policies visible to the caller: org admins see every policy in their org (the org-wide policy has team_id null, plus each team's additional policy); other callers see the org-wide policy and their own team's policy. Unlike GET /guardrails, rows are returned per scope so a team can see which rules it owns versus which the org mandates.
# Test content against guardrails
Source: https://docs.mka1.com/api-reference/guardrails/test-content-against-guardrails
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/guardrails/test
Test a piece of content against the caller's effective guardrails (org-wide policy plus team policy) without generating an answer. Classifier guardrails call their configured model and incur inference usage; API keys additionally require write:responses and must pass the spend budget gate. Useful for debugging and validating guardrail configurations. Returns a report indicating whether the content passed and which guardrail was triggered if any.
# Update guardrails policy
Source: https://docs.mka1.com/api-reference/guardrails/update-guardrails-policy
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/guardrails
Replace a guardrails policy. Classifier models must be active and declare structured-output support; replace the example model ID with a suitable model from your organization. Omit team_id to set the org-wide policy (org admin only); provide team_id to set that team's additional policy (org admins may target any team in their org, other callers only their own team). The org-wide policy applies to every team; a team policy is enforced in addition to it — configuring a team policy never weakens the org-wide one.
# Create a new version
Source: https://docs.mka1.com/api-reference/prompts/create-a-new-version
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/prompts/{id}/versions
Creates a new version of a prompt. The new version automatically becomes the active version. Fields not provided are carried forward from the previous version.
# Create a prompt
Source: https://docs.mka1.com/api-reference/prompts/create-a-prompt
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/prompts
Creates a new prompt with its first version. The template supports {{variable}} placeholders.
# Delete a prompt
Source: https://docs.mka1.com/api-reference/prompts/delete-a-prompt
https://apigw.mka1.com/speakeasy.json delete /api/v1/llm/prompts/{id}
Deletes a prompt and all its versions.
# Get a prompt
Source: https://docs.mka1.com/api-reference/prompts/get-a-prompt
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/prompts/{id}
Retrieves a prompt by its ID, including the active template. Pass `version` to get a specific version's template. Pass `variables` as a JSON-encoded map to render the template with substitutions.
# Get a specific version
Source: https://docs.mka1.com/api-reference/prompts/get-a-specific-version
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/prompts/{id}/versions/{version}
Retrieves a specific version of a prompt by version number.
# List prompts
Source: https://docs.mka1.com/api-reference/prompts/list-prompts
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/prompts
Returns a paginated list of prompts owned by the authenticated user.
# List versions
Source: https://docs.mka1.com/api-reference/prompts/list-versions
https://apigw.mka1.com/speakeasy.json get /api/v1/llm/prompts/{id}/versions
Returns the version history of a prompt, ordered by version number.
# Rollback to a version
Source: https://docs.mka1.com/api-reference/prompts/rollback-to-a-version
https://apigw.mka1.com/speakeasy.json post /api/v1/llm/prompts/{id}/rollback
Sets the active version of a prompt to a previous version. This does not delete newer versions — it only changes which version is active.
# Update a prompt
Source: https://docs.mka1.com/api-reference/prompts/update-a-prompt
https://apigw.mka1.com/speakeasy.json put /api/v1/llm/prompts/{id}
Updates prompt metadata. To update the template content, create a new version instead.
# Get display currency
Source: https://docs.mka1.com/api-reference/settings/get-display-currency
https://apigw.mka1.com/speakeasy.json get /api/v1/budgeting/settings/currency
# Set display currency
Source: https://docs.mka1.com/api-reference/settings/set-display-currency
https://apigw.mka1.com/speakeasy.json put /api/v1/budgeting/settings/currency
ISO 4217 code used for display on budgets and cost reports. No conversion is performed anywhere.
# LogMetric
Source: https://docs.mka1.com/api-reference/tracking-runs/logmetric
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/2.0/mlflow/runs/log-metric
Requer `write:tracking`. Os resultados são restritos à organização e à equipe da chave de API.
# LogParameter
Source: https://docs.mka1.com/api-reference/tracking-runs/logparameter
https://apigw.mka1.com/speakeasy.json?language=es post /api/2.0/mlflow/runs/log-parameter
Requiere `write:tracking`. Los resultados están restringidos a la organización y al equipo de la clave de API.
# Get apiv1budgetingbillingorg
Source: https://docs.mka1.com/api-reference/billing/get-apiv1budgetingbillingorg
https://apigw.mka1.com/speakeasy.json?language=pt-BR get /api/v1/budgeting/billing/org
# Get apiv1budgetingbillingorginvoices
Source: https://docs.mka1.com/api-reference/billing/get-apiv1budgetingbillingorginvoices
https://apigw.mka1.com/speakeasy.json?language=pt-BR get /api/v1/budgeting/billing/org/invoices
# Post apiv1budgetingbillingorgportal session
Source: https://docs.mka1.com/api-reference/billing/post-apiv1budgetingbillingorgportal-session
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/v1/budgeting/billing/org/portal-session
# Post apiv1budgetingbillingorgsetup session
Source: https://docs.mka1.com/api-reference/billing/post-apiv1budgetingbillingorgsetup-session
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/v1/budgeting/billing/org/setup-session
# Put apiv1budgetingbillingorgenabled
Source: https://docs.mka1.com/api-reference/billing/put-apiv1budgetingbillingorgenabled
https://apigw.mka1.com/speakeasy.json?language=pt-BR put /api/v1/budgeting/billing/org/enabled
# Put apiv1budgetingbillingorgprofile
Source: https://docs.mka1.com/api-reference/billing/put-apiv1budgetingbillingorgprofile
https://apigw.mka1.com/speakeasy.json?language=pt-BR put /api/v1/budgeting/billing/org/profile
# Clear this org's auto-model override for an endpoint
Source: https://docs.mka1.com/api-reference/models/clear-this-orgs-auto-model-override-for-an-endpoint
https://apigw.mka1.com/speakeasy.json?language=pt-BR delete /api/v1/llm/models/auto/{endpoint}
Remove a substituição por org para o endpoint. As solicitações subsequentes `model: "auto"` passam a utilizar o padrão YAML do operador novamente.
# LogBatch
Source: https://docs.mka1.com/api-reference/tracking-runs/logbatch
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/2.0/mlflow/runs/log-batch
Requer `write:tracking`. Os resultados são restritos à organização e à equipe da chave de API.
# LogInputs
Source: https://docs.mka1.com/api-reference/tracking-runs/loginputs
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/2.0/mlflow/runs/log-inputs
Requer `write:tracking`. Os resultados são restritos à organização e à equipe da chave de API.
# LogMetric
Source: https://docs.mka1.com/api-reference/tracking-runs/logmetric
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/2.0/mlflow/runs/log-metric
Requer `write:tracking`. Os resultados são restritos à organização e à equipe da chave de API.
# Get apiv1budgetingbillingorg
Source: https://docs.mka1.com/api-reference/billing/get-apiv1budgetingbillingorg
https://apigw.mka1.com/speakeasy.json?language=pt-BR get /api/v1/budgeting/billing/org
# Get apiv1budgetingbillingorginvoices
Source: https://docs.mka1.com/api-reference/billing/get-apiv1budgetingbillingorginvoices
https://apigw.mka1.com/speakeasy.json?language=pt-BR get /api/v1/budgeting/billing/org/invoices
# Post apiv1budgetingbillingorgportal session
Source: https://docs.mka1.com/api-reference/billing/post-apiv1budgetingbillingorgportal-session
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/v1/budgeting/billing/org/portal-session
# Post apiv1budgetingbillingorgsetup session
Source: https://docs.mka1.com/api-reference/billing/post-apiv1budgetingbillingorgsetup-session
https://apigw.mka1.com/speakeasy.json?language=pt-BR post /api/v1/budgeting/billing/org/setup-session
# Put apiv1budgetingbillingorgenabled
Source: https://docs.mka1.com/api-reference/billing/put-apiv1budgetingbillingorgenabled
https://apigw.mka1.com/speakeasy.json?language=pt-BR put /api/v1/budgeting/billing/org/enabled
# Put apiv1budgetingbillingorgprofile
Source: https://docs.mka1.com/api-reference/billing/put-apiv1budgetingbillingorgprofile
https://apigw.mka1.com/speakeasy.json?language=pt-BR put /api/v1/budgeting/billing/org/profile