Skip to main content
Opik Documentation

Search documentation

Type to search this documentation.

On this pageOverview

Opik Query Language (OQL)

OQL provides a powerful, SQL-like syntax for filtering data in Opik. It's used with various SDK methods like searchPrompts(), searchTraces(), and searchThreads() to find exactly the data you need using expressive filter conditions.

TypeScript
// Exact match
'name = "greeting-prompt"';

// Not equal
'name != "old-prompt"';

// Contains substring (case-insensitive)
'name contains "greeting"';

// Does not contain substring
'name not_contains "deprecated"';

// Starts with prefix
'name starts_with "prod-"';

// Ends with suffix
'name ends_with "-v2"';
TypeScript
// Greater than (alphabetical for strings, numeric for numbers)
'name > "m"'; // Names starting with n-z
'duration > 300'; // Threads longer than 300 seconds

// Less than (alphabetical for strings, numeric for numbers)
'name < "m"'; // Names starting with a-l
'number_of_messages < 5'; // Threads with fewer than 5 messages

// Greater than or equal
'feedback_scores.quality >= 0.8';

// Less than or equal
'duration <= 600';
TypeScript
// Equality
'number_of_messages = 3';

// Not equal
'duration != 0';

// Check if field is empty
'feedback_scores.quality is_empty';

// Check if field is not empty
'feedback_scores.quality is_not_empty';
TypeScript
// Use ISO 8601 format for dates
'start_time >= "2024-01-01T00:00:00Z"';
'end_time < "2024-12-31T23:59:59Z"';

Used for fields with a fixed set of values, such as environment:

TypeScript
// Exact match
'environment = "production"';

// Not equal
'environment != "development"';

// Match any of a set of values
'environment in ("production", "staging")';

// Exclude a set of values
'environment not_in ("development", "local")';
TypeScript
// Check if list contains value
'tags contains "production"';

// Check if list does not contain value
'tags not_contains "experimental"';

Use AND to combine multiple filter conditions. All conditions must be true for a result to match:

TypeScript
// Multiple conditions with AND
'tags contains "production" AND name contains "greeting" AND created_by = "user@example.com"';

// Complex multi-field filtering
'name starts_with "prod-" AND tags contains "stable" AND name not_contains "deprecated"';
TypeScript
import { Opik } from "opik";

const client = new Opik();

// Filter by single tag
const prod = await client.searchPrompts('tags contains "production"');

// Combine name pattern and tag
const approved = await client.searchPrompts(
  'name starts_with "prod-" AND tags contains "qa-approved"'
);

// Multiple conditions
const results = await client.searchPrompts(
  'created_by = "user@example.com" AND tags contains "production" AND name not_contains "deprecated"'
);
TypeScript
import { Opik } from "opik";

const client = new Opik();

// Filter by status
const activeThreads = await client.searchThreads({
  projectName: "my-project",
  filterString: 'status = "active"'
});

// Filter by duration and message count
const longConversations = await client.searchThreads({
  projectName: "my-project",
  filterString: 'duration > 300 AND number_of_messages >= 5'
});

// Filter by feedback score
const highQualityThreads = await client.searchThreads({
  projectName: "my-project",
  filterString: 'feedback_scores.quality > 0.8'
});

// Filter by empty feedback score
const unratedThreads = await client.searchThreads({
  projectName: "my-project",
  filterString: 'feedback_scores.quality is_empty'
});

// Filter by environment
const prodThreads = await client.searchThreads({
  projectName: "my-project",
  filterString: 'environment = "production"'
});

// Filter by multiple environments
const stagingOrProdThreads = await client.searchThreads({
  projectName: "my-project",
  filterString: 'environment in ("production", "staging")'
});

// Filter by tags and metadata
const importantProdThreads = await client.searchThreads({
  projectName: "my-project",
  filterString: 'tags contains "important" AND metadata.environment = "production"'
});

// Filter by date range
const recentThreads = await client.searchThreads({
  projectName: "my-project",
  filterString: 'start_time >= "2024-01-01T00:00:00Z"'
});
TypeScript
import { Opik } from "opik";

const client = new Opik();

// Filter by metadata
const traces = await client.searchTraces({
  projectName: "my-project",
  filterString: 'metadata.model = "gpt-5"'
});

// Filter by feedback scores
const goodTraces = await client.searchTraces({
  projectName: "my-project",
  filterString: 'feedback_scores.accuracy > 0.9'
});

// Filter by environment
const prodTraces = await client.searchTraces({
  projectName: "my-project",
  filterString: 'environment = "production"'
});

// Combine environment with other filters
const goodProdTraces = await client.searchTraces({
  projectName: "my-project",
  filterString: 'environment = "production" AND feedback_scores.accuracy > 0.9'
});

Always wrap string values in double quotes:

TypeScript
// ✅ Correct - double quotes around values
await client.searchPrompts('name = "my-prompt"');
await client.searchPrompts('tags contains "production"');

// ❌ Incorrect - missing quotes
await client.searchPrompts("name = my-prompt"); // Will fail

// ❌ Incorrect - single quotes
await client.searchPrompts("name = 'my-prompt'"); // Will fail
TypeScript
try {
  const results = await client.searchPrompts("invalid syntax ===");
} catch (error) {
  console.error("Invalid OQL syntax:", error.message);
}
  1. Use descriptive tag hierarchies - Structure tags like "production", "staging", "team-alpha" for effective filtering
  2. Use naming conventions - Implement consistent naming patterns (e.g., "prod-" prefix) to enable powerful filtering
  3. Handle errors - Always wrap OQL queries in try-catch blocks to handle syntax errors gracefully
Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu