API Users
Pull your team's Contexts into any product surface.
Use Oi as the prompt source of truth for assistants, internal tools, jobs, and workflow automation.
Why developers care
No prompt strings in code
Fetch one shared Context instead of hardcoding prompts into product routes, workers, and tools.
One source of truth
Use the same context across assistants, internal tools, jobs, and product workflows.
Update without deploys
Change the Context in Oi and let clients pick up the latest version.
Public to private path
Start from public contexts, then use private org-specific versions through the same API shape.
Documentation
Contexts
Context API
Get Context
Fetch one Context directly. Use the Context slug, for example `designer`.
# current version
curl -sS \
-H "Authorization: Bearer $OI_API_KEY" \
"https://api.oioioi.ai/v1/contexts/:slug"
# specific historical version
curl -sS \
-H "Authorization: Bearer $OI_API_KEY" \
"https://api.oioioi.ai/v1/contexts/:slug?version=2"from urllib.request import Request, urlopen
request = Request(
"https://api.oioioi.ai/v1/contexts/:slug",
headers={"Authorization": "Bearer " + OI_API_KEY},
)
with urlopen(request) as response:
print(response.read().decode("utf-8"))const response = await fetch("https://api.oioioi.ai/v1/contexts/:slug", {
headers: {
Authorization: `Bearer ${process.env.OI_API_KEY}`,
},
});
const payload = await response.json();
console.log(payload.structuredData);// Current version.
const response = await fetch(
"https://api.oioioi.ai/v1/contexts/:slug",
{
headers: {
Authorization: `Bearer ${process.env.OI_API_KEY ?? ""}`,
},
},
);
// Specific historical version.
const versionedResponse = await fetch(
"https://api.oioioi.ai/v1/contexts/:slug?version=2",
{
headers: {
Authorization: `Bearer ${process.env.OI_API_KEY ?? ""}`,
},
},
);
const payload = (await response.json()) as GetContextResponse;
const versionedPayload = (await versionedResponse.json()) as GetContextResponse;
console.log(payload.structuredData.instructions);
console.log(versionedPayload.structuredData.version);var request = java.net.http.HttpRequest.newBuilder()
.uri(java.net.URI.create("https://api.oioioi.ai/v1/contexts/:slug"))
.header("Authorization", "Bearer " + System.getenv("OI_API_KEY"))
.build();
var client = java.net.http.HttpClient.newHttpClient();
var response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());req, err := http.NewRequest(
http.MethodGet,
"https://api.oioioi.ai/v1/contexts/:slug",
nil,
)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("OI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))require "net/http"
require "uri"
uri = URI("https://api.oioioi.ai/v1/contexts/:slug")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("OI_API_KEY")}"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
puts response.bodyList Contexts
Use limit and cursor for simple pagination. Start here when you want to see what your team has available.
# default fields include context and structuredData
curl -sS \
-H "Authorization: Bearer $OI_API_KEY" \
"https://api.oioioi.ai/v1/contexts?limit=10"
# optional: request the same default fields explicitly
curl -sS \
-H "Authorization: Bearer $OI_API_KEY" \
"https://api.oioioi.ai/v1/contexts?limit=10&include=context,structured"from urllib.request import Request, urlopen
request = Request(
"https://api.oioioi.ai/v1/contexts?limit=10",
headers={"Authorization": "Bearer " + OI_API_KEY},
)
with urlopen(request) as response:
print(response.read().decode("utf-8"))const response = await fetch("https://api.oioioi.ai/v1/contexts?limit=10", {
headers: {
Authorization: `Bearer ${process.env.OI_API_KEY}`,
},
});
const payload = await response.json();
console.log(payload.items[0]?.context);// Default fields include context and structuredData.
const defaultResponse = await fetch("https://api.oioioi.ai/v1/contexts?limit=10", {
headers: {
Authorization: `Bearer ${process.env.OI_API_KEY ?? ""}`,
},
});
const defaultPayload = (await defaultResponse.json()) as ListContextsResponse;
console.log(defaultPayload.items[0]?.context);
console.log(defaultPayload.items[0]?.structuredData.name);
// Specific fields to include.
const structuredResponse = await fetch(
"https://api.oioioi.ai/v1/contexts?limit=10&include=context,structured",
{
headers: {
Authorization: `Bearer ${process.env.OI_API_KEY ?? ""}`,
},
},
);
const structuredPayload = (await structuredResponse.json()) as ListContextsResponse;
console.log(structuredPayload.items[0]?.context);
console.log(structuredPayload.items[0]?.structuredData.name);var request = java.net.http.HttpRequest.newBuilder()
.uri(java.net.URI.create("https://api.oioioi.ai/v1/contexts?limit=10"))
.header("Authorization", "Bearer " + System.getenv("OI_API_KEY"))
.build();
var client = java.net.http.HttpClient.newHttpClient();
var response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());req, err := http.NewRequest(
http.MethodGet,
"https://api.oioioi.ai/v1/contexts?limit=10",
nil,
)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("OI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))require "net/http"
require "uri"
uri = URI("https://api.oioioi.ai/v1/contexts?limit=10")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("OI_API_KEY")}"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
puts response.bodyContext Request and Response Types
Use these language definitions as the query parameter and response shape reference. These GET endpoints do not accept JSON request bodies.
Did you know?
- `context` is the compiled reusable Context prompt.
- `structuredData` is the full Context object for UI, debugging, analytics, or custom client behavior.
type Guardrail = {
name: string;
slug: string;
summary?: string;
isPublic?: boolean;
};
type Capability = {
providerKey: string;
capabilityKey: string;
label: string;
description?: string;
privileges?: string[];
accessLevel?: "read" | "write" | "admin" | "unknown";
usageGuidance?: string;
source: "built_in" | "discovered" | "custom";
status: "available" | "unavailable" | "requires_auth";
};
type ContextStructuredData = {
version?: number;
name: string;
slug: string;
description: string;
personality: string;
operatingStyle: string;
scope?: string;
decisionRules?: string[];
instructions: string;
capabilities?: Capability[];
guardrails?: Guardrail[];
};
type ContextResponse = {
context: string;
structuredData: ContextStructuredData;
usage?: {
usageEventId: string;
source: "api";
operation: "get_context";
promptTokenEstimate?: number;
};
};
type ListContextsResponse = {
items: ContextResponse[];
pagination: {
page: number;
pageSize: number;
totalCount: number;
totalPages: number;
nextCursor?: string;
hasNextPage: boolean;
};
};
type ListContextsQueryParams = {
cursor?: string;
limit?: number;
include?: "context" | "structured" | "context,structured";
};
type GetContextPathParams = {
slug: string;
};
type GetContextQueryParams = {
version?: number;
};
type GetContextResponse = ContextResponse;from typing import Literal, NotRequired, TypedDict
class Capability(TypedDict, total=False):
providerKey: str
capabilityKey: str
label: str
description: str
privileges: list[str]
accessLevel: Literal["read", "write", "admin", "unknown"]
usageGuidance: str
source: Literal["built_in", "discovered", "custom"]
status: Literal["available", "unavailable", "requires_auth"]
class ContextStructuredData(TypedDict, total=False):
version: int
name: str
slug: str
description: str
personality: str
operatingStyle: str
scope: str
decisionRules: list[str]
instructions: str
capabilities: list[Capability]
guardrails: list[dict[str, str | bool]]
order: int
class ContextResponse(TypedDict):
context: str
structuredData: ContextStructuredData
usage: NotRequired[dict[str, str | int]]
class ListContextsResponse(TypedDict, total=False):
items: list[ContextResponse]
pagination: dict[str, int | str]
class ListContextsQueryParams(TypedDict, total=False):
cursor: str
limit: int
include: Literal["context", "structured", "context,structured"]
class GetContextPathParams(TypedDict):
slug: str
class GetContextQueryParams(TypedDict, total=False):
version: int
class GetContextResponse(ContextResponse):
pass/**
* @typedef {Object} ContextStructuredData
* @property {number=} version
* @property {string} name
* @property {string} slug
* @property {string} description
* @property {string} personality
* @property {string} operatingStyle
* @property {string=} scope
* @property {string[]=} decisionRules
* @property {string} instructions
* @property {{ providerKey: string, capabilityKey: string, label: string, description?: string, privileges?: string[], accessLevel?: "read" | "write" | "admin" | "unknown", usageGuidance?: string, source: "built_in" | "discovered" | "custom", status: "available" | "unavailable" | "requires_auth" }[]=} capabilities
* @property {{ name: string, slug: string, summary?: string, isPublic?: boolean }[]=} guardrails
* @property {number} order
*
* @typedef {Object} ContextResponse
* @property {string} context
* @property {ContextStructuredData} structuredData
* @property {{ usageEventId: string, source: "api", operation: "get_context", promptTokenEstimate?: number }=} usage
*/public record Capability(
String providerKey,
String capabilityKey,
String label,
String description,
List<String> privileges,
String accessLevel,
String usageGuidance,
String source,
String status
) {}
public record ContextStructuredData(
Integer version,
String name,
String slug,
String description,
String personality,
String operatingStyle,
String scope,
List<String> decisionRules,
String instructions,
List<Capability> capabilities,
int order
) {}
public record ContextResponse(
String context,
ContextStructuredData structuredData,
Map<String, Object> usage
) {}type Capability struct {
ProviderKey string `json:"providerKey"`
CapabilityKey string `json:"capabilityKey"`
Label string `json:"label"`
Description *string `json:"description,omitempty"`
Privileges []string `json:"privileges,omitempty"`
AccessLevel *string `json:"accessLevel,omitempty"`
UsageGuidance *string `json:"usageGuidance,omitempty"`
Source string `json:"source"`
Status string `json:"status"`
}
type ContextStructuredData struct {
Version *int `json:"version,omitempty"`
Name string `json:"name"`
Slug string `json:"slug"`
Description string `json:"description"`
Personality string `json:"personality"`
OperatingStyle string `json:"operatingStyle"`
Instructions string `json:"instructions"`
Capabilities []Capability `json:"capabilities,omitempty"`
}
type ContextResponse struct {
Context string `json:"context"`
StructuredData ContextStructuredData `json:"structuredData"`
Usage map[string]interface{} `json:"usage,omitempty"`
}module Oi
class Capability < T::Struct
const :provider_key, String
const :capability_key, String
const :label, String
prop :description, T.nilable(String)
prop :privileges, T.nilable(T::Array[String])
prop :access_level, T.nilable(String)
prop :usage_guidance, T.nilable(String)
const :source, String
const :status, String
end
class ContextStructuredData < T::Struct
prop :version, T.nilable(Integer)
const :name, String
const :slug, String
const :description, String
const :personality, String
const :operating_style, String
const :instructions, String
prop :capabilities, T.nilable(T::Array[Capability])
end
class ContextResponse < T::Struct
const :context, String
const :structured_data, ContextStructuredData
prop :usage, T.nilable(T::Hash[String, T.untyped])
end
endContext Example Responses
Use these JSON payloads as concrete examples of Context API responses.
Get Context
{
// truncated for example
"context": "## Scope\n\nFocus on UX quality, product flows, missing states, and interaction gaps...",
"structuredData": {
"version": 3,
"name": "Designer",
"slug": "designer",
"description": "Reviews flows, UX details, and design direction.",
"personality": "Direct, sharp, and product-minded.",
"operatingStyle": "Give feedback in priority order with concrete fixes.",
"scope": "Focus on UX quality, product flows, missing states, and interaction gaps.",
"decisionRules": [
"Start with the most important friction or confusion.",
"Call out missing states before visual polish.",
"Be specific about the screen, component, or step."
],
"instructions": "Act as the organization's design collaborator.",
"capabilities": [
{
"providerKey": "figma",
"capabilityKey": "file.read",
"label": "Read Figma files",
"description": "Inspect Figma frames before giving design feedback.",
"privileges": ["file.read"],
"accessLevel": "read",
"usageGuidance": "Use when a task references a Figma file or design review.",
"source": "built_in",
"status": "available"
}
],
"guardrails": [
{
"name": "Warn before long prompt",
"slug": "warn-before-long-prompt",
"summary": "Warn the user before producing unusually long prompt content.",
"isPublic": true
}
]
},
"usage": {
"usageEventId": "usage_123",
"source": "api",
"operation": "get_context",
"promptTokenEstimate": 620
}
}List Contexts
{
"items": [
{
// truncated for example
"context": "## Scope\n\nFocus on UX quality, product flows, missing states, and interaction gaps...",
"structuredData": {
"version": 3,
"name": "Designer",
"slug": "designer",
"description": "Reviews flows, UX details, and design direction.",
"personality": "Direct, sharp, and product-minded.",
"operatingStyle": "Give feedback in priority order with concrete fixes.",
"scope": "Focus on UX quality, product flows, missing states, and interaction gaps.",
"decisionRules": [
"Start with the most important friction or confusion.",
"Call out missing states before visual polish.",
"Be specific about the screen, component, or step."
],
"instructions": "Act as the organization's design collaborator.",
"capabilities": [
{
"providerKey": "figma",
"capabilityKey": "file.read",
"label": "Read Figma files",
"description": "Inspect Figma frames before giving design feedback.",
"privileges": ["file.read"],
"accessLevel": "read",
"usageGuidance": "Use when a task references a Figma file or design review.",
"source": "built_in",
"status": "available"
}
],
"guardrails": [
{
"name": "Warn before long prompt",
"slug": "warn-before-long-prompt",
"summary": "Warn the user before producing unusually long prompt content.",
"isPublic": true
}
],
}
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"totalCount": 24,
"totalPages": 3,
"nextCursor": "context#designer",
"hasNextPage": true
}
}Workflows
Workflow API
List Workflows
List organization Workflows for the API key's organization. Use `q`, `limit`, `page`, or `cursor` to search and paginate.
curl -sS \
-H "Authorization: Bearer $OI_API_KEY" \
"https://api.oioioi.ai/v1/workflows?limit=10"const response = await fetch("https://api.oioioi.ai/v1/workflows?limit=10&include=structured", {
headers: {
Authorization: `Bearer ${process.env.OI_API_KEY ?? ""}`,
},
});
const payload = (await response.json()) as ListWorkflowResponse;
console.log(payload.items.map((workflow) => workflow.structuredData?.workflowId));Get Workflow
Fetch one organization Workflow by `workflowId`. Use `?version=2` to request a historical version.
curl -sS \
-H "Authorization: Bearer $OI_API_KEY" \
"https://api.oioioi.ai/v1/workflows/:workflowId"const response = await fetch(
"https://api.oioioi.ai/v1/workflows/:workflowId",
{
headers: {
Authorization: `Bearer ${process.env.OI_API_KEY ?? ""}`,
},
},
);
const payload = (await response.json()) as WorkflowResponse;
console.log(payload.context);
console.log(payload.structuredData.name);Workflow Response Type
Organization Workflow responses follow the same top-level shape as Contexts: `context` plus `structuredData`. Use `/v1/workflows` with your organization API key.
type Guardrail = {
name: string;
slug: string;
summary?: string;
isPublic?: boolean;
};
type Capability = {
providerKey: string;
capabilityKey: string;
label: string;
description?: string;
privileges?: string[];
accessLevel?: "read" | "write" | "admin" | "unknown";
usageGuidance?: string;
source: "built_in" | "discovered" | "custom";
status: "available" | "unavailable" | "requires_auth";
};
type Context = {
slug: string;
name: string;
description: string;
context?: string;
personality: string;
operatingStyle: string;
scope?: string;
decisionRules: string[];
instructions: string;
capabilities?: Capability[];
guardrails: Guardrail[];
responsibility: string;
handoffInstruction: string;
required: boolean;
order: number;
};
type WorkflowStructuredData = {
slug: string;
organizationName?: string;
organizationSlug?: string;
organizationLogoUrl?: string;
name: string;
description: string;
audience: string;
bestFor: string;
contextCount: number;
installCount: number;
publishedAt: string;
invocationCommand: string;
exampleUseCases: string[];
autoSelectEnabled: boolean;
constraints: string;
experiments: string;
measurement: string;
definitionOfDone: string;
postExecutionFollowUp: string;
contexts: Context[];
guardrails: Guardrail[];
};
type WorkflowResponse = {
context: string;
structuredData: WorkflowStructuredData;
};
type PublicWorkflowSummary = {
entityId: string;
slug: string;
organizationName?: string;
organizationSlug?: string;
organizationLogoUrl?: string;
name: string;
shortDescription: string;
description: string;
audience: string;
bestFor: string;
contextCount: number;
installCount: number;
publishedAt: string;
invocationCommand: string;
exampleUseCases: string[];
autoSelectEnabled: boolean;
contexts: Array<{
name: string;
responsibility: string;
handoffInstruction: string;
}>;
guardrails: Guardrail[];
categories?: string[];
tags?: string[];
};
type PublicWorkflowDetailResponse = WorkflowResponse & {
workflow: PublicWorkflowSummary;
};
type ListWorkflowResponse = {
items: WorkflowResponse[];
pagination: {
page: number;
pageSize: number;
totalCount: number;
totalPages: number;
nextCursor?: string;
hasNextPage: boolean;
};
};from typing import NotRequired, TypedDict
class Guardrail(TypedDict, total=False):
name: str
slug: str
summary: str
isPublic: bool
class Capability(TypedDict, total=False):
providerKey: str
capabilityKey: str
label: str
description: str
privileges: list[str]
accessLevel: str
usageGuidance: str
source: str
status: str
class Context(TypedDict):
slug: str
name: str
description: str
context: NotRequired[str]
personality: str
operatingStyle: str
scope: NotRequired[str]
decisionRules: list[str]
instructions: str
capabilities: NotRequired[list[Capability]]
guardrails: list[Guardrail]
responsibility: str
handoffInstruction: str
required: bool
order: int
class WorkflowStructuredData(TypedDict):
slug: str
name: str
description: str
audience: str
bestFor: str
contextCount: int
installCount: int
publishedAt: str
invocationCommand: str
exampleUseCases: list[str]
autoSelectEnabled: bool
contexts: list[Context]
guardrails: list[Guardrail]
class WorkflowResponse(TypedDict):
context: str
structuredData: WorkflowStructuredData
class PublicWorkflowSummary(TypedDict, total=False):
entityId: str
slug: str
organizationName: str
organizationSlug: str
organizationLogoUrl: str
name: str
shortDescription: str
description: str
audience: str
bestFor: str
contextCount: int
installCount: int
publishedAt: str
invocationCommand: str
exampleUseCases: list[str]
autoSelectEnabled: bool
contexts: list[dict[str, str]]
guardrails: list[Guardrail]
categories: list[str]
tags: list[str]
class PublicWorkflowDetailResponse(WorkflowResponse):
workflow: PublicWorkflowSummary
class ListWorkflowResponse(TypedDict):
items: list[WorkflowResponse]
pagination: dict[str, int | str]/**
* @typedef {Object} Guardrail
* @property {string} name
* @property {string} slug
* @property {string=} summary
* @property {boolean=} isPublic
*
* @typedef {Object} Context
* @property {string} slug
* @property {string} name
* @property {string} description
* @property {string=} context
* @property {string} personality
* @property {string} operatingStyle
* @property {string[]=} decisionRules
* @property {string} instructions
* @property {{ providerKey: string, capabilityKey: string, label: string, description?: string, privileges?: string[], accessLevel?: "read" | "write" | "admin" | "unknown", usageGuidance?: string, source: "built_in" | "discovered" | "custom", status: "available" | "unavailable" | "requires_auth" }[]=} capabilities
* @property {Guardrail[]} guardrails
* @property {string} responsibility
* @property {string} handoffInstruction
* @property {boolean} required
* @property {number} order
*
* @typedef {Object} WorkflowResponse
* @property {string} context
* @property {{ slug: string, name: string, contexts: Context[], guardrails: Array<{ name: string, slug: string, summary?: string, isPublic?: boolean }> }} structuredData
*
* @typedef {Object} PublicWorkflowDetailResponse
* @property {string} context
* @property {{ slug: string, name: string, contexts: Context[], guardrails: Array<{ name: string, slug: string, summary?: string, isPublic?: boolean }> }} structuredData
* @property {{ entityId: string, slug: string, organizationSlug?: string, name: string, shortDescription: string, description: string }} workflow
*
* @typedef {Object} ListWorkflowResponse
* @property {WorkflowResponse[]} items
* @property {{ page: number, pageSize: number, totalCount: number, totalPages: number, nextCursor?: string, hasNextPage: boolean }} pagination
*/public record Guardrail(
String name,
String slug,
String summary,
Boolean isPublic
) {}
public record Capability(
String providerKey,
String capabilityKey,
String label,
String description,
List<String> privileges,
String accessLevel,
String usageGuidance,
String source,
String status
) {}
public record Context(
String slug,
String name,
String description,
String context,
String personality,
String operatingStyle,
List<String> decisionRules,
String instructions,
List<Capability> capabilities,
List<Guardrail> guardrails,
String responsibility,
String handoffInstruction,
boolean required,
int order
) {}
public record WorkflowResponse(
String context,
WorkflowStructuredData structuredData
) {}
public record PublicWorkflowSummary(
String entityId,
String slug,
String organizationSlug,
String name,
String shortDescription,
String description
) {}
public record PublicWorkflowDetailResponse(
String context,
WorkflowStructuredData structuredData,
PublicWorkflowSummary workflow
) {}
public record ListWorkflowResponse(
List<WorkflowResponse> items,
Map<String, Object> pagination
) {}type Guardrail struct {
Name string `json:"name"`
Slug string `json:"slug"`
Summary *string `json:"summary,omitempty"`
IsPublic *bool `json:"isPublic,omitempty"`
}
type Capability struct {
ProviderKey string `json:"providerKey"`
CapabilityKey string `json:"capabilityKey"`
Label string `json:"label"`
Description *string `json:"description,omitempty"`
Privileges []string `json:"privileges,omitempty"`
AccessLevel *string `json:"accessLevel,omitempty"`
UsageGuidance *string `json:"usageGuidance,omitempty"`
Source string `json:"source"`
Status string `json:"status"`
}
type Context struct {
Slug string `json:"slug"`
Name string `json:"name"`
Description string `json:"description"`
Context *string `json:"context,omitempty"`
Personality string `json:"personality"`
OperatingStyle string `json:"operatingStyle"`
Instructions string `json:"instructions"`
Capabilities []Capability `json:"capabilities,omitempty"`
Guardrails []Guardrail `json:"guardrails"`
Responsibility string `json:"responsibility"`
HandoffInstruction string `json:"handoffInstruction"`
Required bool `json:"required"`
Order int `json:"order"`
}
type WorkflowResponse struct {
Context string `json:"context"`
StructuredData WorkflowStructuredData `json:"structuredData"`
}
type PublicWorkflowSummary struct {
EntityID string `json:"entityId"`
Slug string `json:"slug"`
OrganizationSlug *string `json:"organizationSlug,omitempty"`
Name string `json:"name"`
ShortDescription string `json:"shortDescription"`
Description string `json:"description"`
}
type PublicWorkflowDetailResponse struct {
Context string `json:"context"`
StructuredData WorkflowStructuredData `json:"structuredData"`
Workflow PublicWorkflowSummary `json:"workflow"`
}
type ListWorkflowResponse struct {
Items []WorkflowResponse `json:"items"`
Pagination map[string]interface{} `json:"pagination"`
}module Oi
class Guardrail < T::Struct
const :name, String
const :slug, String
prop :summary, T.nilable(String)
prop :is_public, T.nilable(T::Boolean)
end
class Capability < T::Struct
const :provider_key, String
const :capability_key, String
const :label, String
prop :description, T.nilable(String)
prop :privileges, T.nilable(T::Array[String])
prop :access_level, T.nilable(String)
prop :usage_guidance, T.nilable(String)
const :source, String
const :status, String
end
class Context < T::Struct
const :slug, String
const :name, String
const :description, String
prop :context, T.nilable(String)
const :personality, String
const :operating_style, String
const :instructions, String
prop :capabilities, T.nilable(T::Array[Capability])
const :guardrails, T::Array[Guardrail]
const :responsibility, String
const :handoff_instruction, String
const :required, T::Boolean
const :order, Integer
end
class WorkflowResponse < T::Struct
const :context, String
const :structured_data, WorkflowStructuredData
end
class PublicWorkflowSummary < T::Struct
const :entity_id, String
const :slug, String
prop :organization_slug, T.nilable(String)
const :name, String
const :short_description, String
const :description, String
end
class PublicWorkflowDetailResponse < T::Struct
const :context, String
const :structured_data, WorkflowStructuredData
const :workflow, PublicWorkflowSummary
end
endWorkflow Example Responses
Guardrails appear inside the compiled Workflow `context` and the `structuredData` runtime details when present.
Get Workflow
{
// truncated for example
"context": "# Launch Review\n\nRun a launch-readiness review...",
"structuredData": {
"slug": "launch-review",
"organizationName": "Oi",
"organizationSlug": "oi",
"organizationLogoUrl": "https://oioioi.ai/og-image.png",
"name": "Launch Review",
"description": "Run a launch-readiness review across positioning, UX, technical risk, and follow-up actions.",
"audience": "Product and growth teams",
"bestFor": "Preparing a release or campaign before it reaches customers.",
"contextCount": 3,
"installCount": 42,
"publishedAt": "2026-04-01T02:15:00.000Z",
"invocationCommand": "oi workflow launch-review <your task here>",
"exampleUseCases": [
"Review this launch plan and identify blockers.",
"Turn this release brief into launch-ready tasks."
],
"autoSelectEnabled": true,
"constraints": "Keep recommendations grounded in the supplied brief and available evidence.",
"experiments": "Suggest lightweight experiments when the launch risk is uncertain.",
"measurement": "Track activation, support volume, conversion, and adoption.",
"definitionOfDone": "Risks are named, owners are clear, and next actions are ready to assign.",
"postExecutionFollowUp": "Review launch metrics and create a follow-up improvement list.",
"contexts": [
{
"slug": "product-manager",
"name": "Product Manager",
"responsibility": "Assess user value, launch scope, and tradeoffs.",
"handoffInstruction": "Pass launch risks and open decisions to the next reviewer.",
"required": true,
"order": 0
},
{
"slug": "designer",
"name": "Designer",
"description": "Use this Context when a product experience needs fast UX critique.",
"context": "# Designer\n\nReview flows, UX details, and design direction.",
"personality": "Direct, sharp, and product-minded.",
"operatingStyle": "Give feedback in priority order with concrete fixes.",
"scope": "Focus on UX quality, product flows, missing states, and interaction gaps.",
"decisionRules": ["Start with the most important friction."],
"instructions": "Act as the organization's design collaborator.",
"capabilities": [
{
"providerKey": "figma",
"capabilityKey": "file.read",
"label": "Read Figma files",
"description": "Inspect Figma frames before giving design feedback.",
"privileges": ["file.read"],
"accessLevel": "read",
"usageGuidance": "Use when a task references a Figma file or design review.",
"source": "built_in",
"status": "available"
}
],
"guardrails": [
{
"name": "Warn before long prompt",
"slug": "warn-before-long-prompt",
"summary": "Warn the user before producing unusually long prompt content.",
"isPublic": true
}
],
"responsibility": "Review UX quality and customer-facing flow.",
"handoffInstruction": "Pass UX risks to engineering.",
"required": true,
"order": 1
}
],
"guardrails": [
{
"name": "Warn before long prompt",
"slug": "warn-before-long-prompt",
"summary": "Warn the user before producing unusually long prompt content.",
"isPublic": true
}
]
},
"workflow": {
"entityId": "workflow_123",
"slug": "launch-review",
"organizationName": "Oi",
"organizationSlug": "oi",
"organizationLogoUrl": "https://oioioi.ai/og-image.png",
"name": "Launch Review",
"shortDescription": "Run a launch-readiness review.",
"description": "Run a launch-readiness review across positioning, UX, technical risk, and follow-up actions."
}
}Get Workflows
{
"items": [
{
// truncated for example
"context": "# Launch Review\n\nRun a launch-readiness review...",
"structuredData": {
"slug": "launch-review",
"name": "Launch Review",
"description": "Run a launch-readiness review across positioning, UX, technical risk, and follow-up actions.",
"organizationName": "Oi",
"organizationSlug": "oi",
"organizationLogoUrl": "https://oioioi.ai/og-image.png",
"audience": "Product and growth teams",
"bestFor": "Preparing a release or campaign before it reaches customers.",
"contextCount": 3,
"installCount": 42,
"publishedAt": "2026-04-01T02:15:00.000Z",
"invocationCommand": "oi workflow launch-review <your task here>",
"exampleUseCases": [
"Review this launch plan and identify blockers.",
"Turn this release brief into launch-ready tasks."
],
"autoSelectEnabled": true,
"constraints": "Keep recommendations grounded in the supplied brief and available evidence.",
"experiments": "Suggest lightweight experiments when the launch risk is uncertain.",
"measurement": "Track activation, support volume, conversion, and adoption.",
"definitionOfDone": "Risks are named, owners are clear, and next actions are ready to assign.",
"postExecutionFollowUp": "Review launch metrics and create a follow-up improvement list.",
"contexts": [
{
"slug": "product-manager",
"name": "Product Manager",
"responsibility": "Assess launch scope, risks, and tradeoffs.",
"handoffInstruction": "Pass open launch decisions to design.",
"required": true,
"order": 0
},
{
"slug": "designer",
"name": "Designer",
"responsibility": "Review UX quality and customer-facing flow.",
"handoffInstruction": "Pass UX risks to engineering.",
"required": true,
"order": 1,
"capabilities": [
{
"providerKey": "figma",
"capabilityKey": "file.read",
"label": "Read Figma files",
"description": "Inspect Figma frames before giving design feedback.",
"privileges": ["file.read"],
"accessLevel": "read",
"usageGuidance": "Use when a task references a Figma file or design review.",
"source": "built_in",
"status": "available"
}
]
}
],
"guardrails": [
{
"name": "Warn before long prompt",
"slug": "warn-before-long-prompt",
"summary": "Warn the user before producing unusually long prompt content.",
"isPublic": true
}
]
}
}
],
"pagination": {
"page": 1,
"pageSize": 10,
"totalCount": 24,
"totalPages": 3,
"nextCursor": "workflow#launch-review",
"hasNextPage": true
}
}Errors
Error payloads use a small JSON shape that can be handled the same way across Context and Workflow endpoints.
{
"error": "entitlement_feature_unavailable(feature:api_access,plan:free,required:pro)",
"feature": "api_access",
"requiredPlan": "pro",
"upgradePath": "/dashboard/organization/billing"
}