Reference
SDK Cheat Sheet
One-page reference for common Onyx SDK calls. Select a language to see the syntax.
Onyx Environment Variables
Set these to control how the SDK scopes requests and where it fetches credentials.
| Env Var | Description | Default |
|---|---|---|
| ONYX_DATABASE_ID | Database UUID used to scope requests; required. | none |
| ONYX_DATABASE_BASE_URL | HTTP base for DB API. | https://api.onyx.dev |
| ONYX_DATABASE_API_KEY | API key for the database; required. | none |
| ONYX_DATABASE_API_SECRET | API secret for the database; required. | none |
| ONYX_AI_BASE_URL | Base URL for AI/chat endpoints. | https://ai.onyx.dev |
| ONYX_DEFAULT_MODEL | Model used by db.chat() shorthand. | onyx |
| ONYX_CONFIG_PATH | Path to JSON credentials file (Node only; ignored on edge). | unset |
| ONYX_DEBUG | When "true", enables request/response logging and config debug output. | false |
| ONYX_STREAM_DEBUG | When "true"/"1", logs streaming connection details. | false |
Initialization Patterns
Initialize the Go SDK with explicit config or environment resolution.
Auto resolution
Resolves credentials from env vars, then onyx-database.json in the project/home directories.
ctx := context.Background()
db, err := onyx.New(ctx, onyx.Config{})
Initialize with config object
Pass credentials directly when you can’t rely on env/file resolution.
ctx := context.Background()
db, err := onyx.New(ctx, onyx.Config{
ApiKey: "YOUR_API_KEY",
ApiSecret: "YOUR_API_SECRET"
})
Optional config fields
| Attribute | Description | Default |
|---|---|---|
| baseUrl | REST base URL for database operations. | https://api.onyx.dev |
| databaseId | Database ID (inferred from DB-scoped keys; set for org-wide keys). | resolved from key |
| aiBaseUrl | Base URL for AI endpoints. | https://ai.onyx.dev |
| defaultModel | Fallback AI model for shorthand chat calls. | onyx |
| partition | Default partition for queries/find/delete. | entity partition |
| ttl | Millis to cache resolved credentials. | 300000 |
| retry | Retry config for idempotent GETs. | 3 retries; 300/600/1200ms |
Core CRUD
Upsert, fetch, update, and delete entities by primary key.
ctx := context.Background()
db, err := onyx.New(ctx, onyx.Config{})
acct := &onyx.Account{Id: "acct_1", Name: "Checking", Balance: 1250}
err = db.Accounts().Save(ctx, acct)
found, err := db.Accounts().Find(ctx, "acct_1")
fmt.Println(found, err)
acct.Balance = 1400
err = db.Accounts().Save(ctx, acct)
err = db.Accounts().Delete(ctx, "acct_1")Atomic Saving
Persist a parent plus related records in one call—no explicit transactions needed.
Cascade save
Save an Account and its Transactions together; all-or-none commit.
acct := &onyx.Account{
Id: "acct_cascade",
Name: "Primary",
Balance: 0,
Transactions: []onyx.Transaction{
{Id: "txn_1", AccountId: "acct_cascade", Amount: 250, Currency: "USD"},
{Id: "txn_2", AccountId: "acct_cascade", Amount: 125, Currency: "USD"},
},
}
err := db
.Cascade("transactions:Transaction(accountId, id)")
.Save(ctx, onyx.TableAccount, acct)Cascade builder
Fluent builder that emits the cascade string.
rel := db
.CascadeBuilder()
.Graph("Transactions")
.GraphType("Transaction")
.TargetField("AccountId")
.SourceField("Id")
fmt.Println(rel.String()) // transactions:Transaction(accountId, id)Cascade string syntax
<field>:<RelatedTable>(<targetField>, <sourceField>) — field: property on the parent holding related rows; RelatedTable: table to upsert; targetField: FK on the related table; sourceField: parent field to copy.
Resolvers
Hydrate related data defined in your schema without extra round trips.
Fetch by id with resolver
Load a transaction and its account in one call.
tx, err := db.Transactions().Resolve("account").Find(ctx, "txn_123")Query with resolver
Filter base table and include related account data.
rows, err := db.Transactions()
.Where(onyx.Eq("status", "posted"))
.Resolve("account")
.List(ctx)Filter by resolver field
Filter using fields exposed by the resolver.
rows, err := db.Transactions()
.Where(onyx.Eq("account.name", "Primary"))
.Resolve("account")
.List(ctx)Bulk Save
Insert many records efficiently by passing a slice to Save.
txns := []onyx.Transaction{
{Id: "txn_batch_1", AccountId: "acct_batch", Amount: 1.99, Currency: "USD"},
{Id: "txn_batch_2", AccountId: "acct_batch", Amount: 12.50, Currency: "USD"},
{Id: "txn_batch_3", AccountId: "acct_batch", Amount: 45.00, Currency: "USD"},
{Id: "txn_batch_4", AccountId: "acct_batch", Amount: 7.25, Currency: "USD"},
}
err = db.Transactions()
.Save(ctx, txns)Query & Filter
Boolean filters, ranges, text contains, ordering, and limits.
txns, err := db.Transactions()
.Where(
onyx.Eq("status", "posted").
And(onyx.Gt("amount", 100)).
And(onyx.Gte("createdAt", "2025-01-01")).
And(onyx.Contains("merchant", "aws")),
)
.OrderBy(onyx.Desc("createdAt"))
.Limit(25)
.List(ctx)Defaults: if you omit Limit() and PageSize(), the API uses its server-side default page size (capped at 1000); responses include NextPage when more rows remain.
Query clauses
| Clause | Signature | What it does |
|---|---|---|
| Where | Where(condition) | Adds a boolean filter to the query. |
| And | Where(...).And(condition) | Chain additional AND conditions. |
| Or | Where(...).Or(condition) | Combine conditions with OR. |
| OrderBy | OrderBy(Asc/Desc("field")) | Sort the result set. |
| GroupBy | GroupBy(fields...) | Group results for aggregates. |
| Distinct | Distinct() | Return unique rows for selected fields. |
| Limit | Limit(n) | Cap number of records returned. |
| PageSize | PageSize(n) | Set page size for streaming pagination. |
| InPartition | InPartition(partition) | Filter to a single partition. |
| Page | Page(nextToken) | Fetch the next cursor page. |
Filters
| Helper | Signature | What it does |
|---|---|---|
| Eq | Eq("field", value) | Equals. |
| Neq | Neq("field", value) | Not equals. |
| Gt | Gt("field", value) | Greater than. |
| Gte | Gte("field", value) | Greater than or equal. |
| Lt | Lt("field", value) | Less than. |
| Lte | Lte("field", value) | Less than or equal. |
| Between | Between("field", low, high) | Inclusive range. |
| Contains | Contains("field", text) | Substring contains (case-sensitive). |
| ContainsIC | ContainsIC("field", text) | Substring contains (case-insensitive). |
| StartsWith | StartsWith("field", text) | Prefix match. |
| InOp | InOp("field", values) | Field in list of values. |
| NotIn | NotIn("field", values) | Field not in list of values. |
| Within | Within("field", subquery) | Field in subquery results. |
| IsNull | IsNull("field") | Field is null. |
| NotNull | NotNull("field") | Field is not null. |
| Search | Search("lucene", minScore) | Lucene text search condition with optional score threshold. |
Select Query
Pick specific columns to return from a table.
rows, err := db.Select("id", "accountId", "amount", "createdAt")
.From(onyx.TableTransaction)
.List(ctx)First or Null
When you expect a single row, use FirstOrNil (alias One).
first, err := db.Transactions()
.Where(onyx.Eq("id", "txn_123"))
.FirstOrNil(ctx)
one, err := db.Transactions()
.Where(onyx.Eq("id", "txn_123"))
.One(ctx)Inner Queries
Filter a table using sub-selects returned from another query.
records := db.Select("accountId")
.From(onyx.TableTransaction)
.Where(onyx.Gt("amount", 1000))
rows, err := db.Accounts()
.Where(onyx.Within("id", records))
.List(ctx)Update Query
Set partial updates for all rows matching a condition.
updated, err := db.Transactions()
.Where(onyx.Eq("status", "pending").And(onyx.Gt("amount", 100))).
.Set(map[string]any{"status": "posted"}).
.Update(ctx)Delete Query
Delete all rows that match a filter.
deletedCount, err := db.Transactions()
.Where(onyx.Eq("status", "archived")).
.Delete(ctx)Group By
Group results by one or more fields to segment metrics.
rows, err := db.Select("merchant", "currency")
.From(onyx.TableTransaction)
.Where(onyx.Eq("status", "posted"))
.GroupBy("merchant", "currency")
.List(ctx)Aggregations
Server-side rollups for dashboards and billing summaries.
rows, err := db.Select(onyx.Sum("amount"), "merchant")
.From(onyx.TableTransaction)
.Where(onyx.Eq("status", "posted"))
.List(ctx)Server-side aggregate helpers
| Function | Signature | What it does |
|---|---|---|
| sum | Sum("field") | Numeric sum of a column. |
| count | Count("field"|"*") | Row count. |
| avg | Avg("field") | Arithmetic mean. |
| min | Min("field") | Smallest value. |
| max | Max("field") | Largest value. |
| median | Median("field") | 50th percentile. |
| percentile | Percentile("field", p) | p-th percentile (0–100). |
| std | Std("field") | Sample standard deviation. |
| variance | Variance("field") | Sample variance. |
| upper | Upper("field") | Uppercase text for grouping/aggregation. |
| lower | Lower("field") | Lowercase text for grouping/aggregation. |
| format | Format("field", "pattern") | Apply Java-style date/number format before grouping. |
| substring | Substring("field", from, length) | Substring of text (0-based offset). |
| replace | Replace("field", pattern, repl) | Regex/substring replacement prior to grouping. |
Streaming Queries
Consume large result sets incrementally and react to live query responses.
iter, err := db.Transactions()
.Where(onyx.Eq("status", "posted"))
.PageSize(100)
.Stream(ctx)
defer iter.Close()
for iter.Next() {
msg := iter.Value()
fmt.Println(msg)
}
err = iter.Err()Full-Text Search
Lucene-style search across tables marked SEARCHABLE in your schema.
All searchable tables
Runs across every table marked SEARCHABLE (optionally set a minimum score).
hits, err := db.Search("error AND status:active", 4.0).Limit(50).List(ctx)Table-scoped search with minScore
Scopes search to a single table and applies a score threshold.
hits, err := db.Transactions()
.Search(`status:posted AND merchant:"AWS"`, 4.4)
.List(ctx)Pagination
Page through ordered results with stable cursors (offset-free).
page1, err := db.Transactions()
.OrderBy(onyx.Asc("createdAt"))
.Limit(50)
.Page(ctx, "")
next := page1.NextPage
if next != "" {
page2, err := db.Transactions()
.OrderBy(onyx.Asc("createdAt"))
.Page(ctx, next)
fmt.Println(page2, err)
}AI Chat
Use the AI endpoint to answer questions that reference your data.
Chat completions
Control model, messages, streaming/raw response options.
resp, err := db.Chat(ctx, onyx.AIChatCompletionRequest{
Model: "onyx",
Messages: []onyx.AIChatMessage{
{Role: "system", Content: "You are a finance assistant. Respond with 3 concise bullet points."},
{Role: "assistant", Content: "I summarize trends and call out anomalies each Friday."},
{Role: "user", Content: "Draft a status update for finance stakeholders."},
},
})
fmt.Println(resp, err)Streaming chat
Stream tokens as they arrive.
stream, err := db.ChatStream(ctx, onyx.AIChatCompletionRequest{
Model: "onyx",
Stream: true,
Messages: []onyx.AIChatMessage{{Role: "user", Content: "List the top 3 spend categories this week."}},
})
defer stream.Close()
for stream.Next() {
chunk := stream.Value()
fmt.Println(chunk)
}
err = stream.Err()Shorthand chat (string in, string out)
Quick one-shot: send a single user prompt and return the first message content.
resp, err := db.Chat(ctx, onyx.AIChatCompletionRequest{
Model: "onyx",
Messages: []onyx.AIChatMessage{
{Role: "user", Content: "Summarize yesterday's transactions in two bullets."},
},
})
summary := resp.Choices[0].Message.Content
fmt.Println(summary, err)List available models
Discover model IDs before picking one.
models, err := db.GetModels(ctx)
for _, m := range models.Data {
fmt.Println(m.ID)
}Get model details
Inspect a specific model's capabilities and limits.
model, err := db.GetModel(ctx, "onyx")
fmt.Println(model, err)Request script approval
Validate a mutation script before execution.
resp, err := db.RequestScriptApproval(ctx, onyx.AIScriptApprovalRequest{
Script: "db.Save({ id: 'acct_1', name: 'Checking' })",
})
fmt.Println(resp, err)Documents
Upload binary files with metadata, fetch with optional resizing, or delete stored documents.
Save a document
Stores metadata in the DB and writes bytes to the database’s _documents path.
payload := []byte("hello")
err := db.Documents().Save(ctx, onyx.Document{
DocumentId: "hello.txt",
Path: "/docs/hello.txt",
MimeType: "text/plain",
Content: payload,
})Get a document
Fetches by documentId; width/height resize images on the fly.
doc, err := db.Documents().Get(ctx, "hello.txt", nil)
fmt.Println(doc, err)Delete a document
Removes the file and its metadata.
err := db.Documents().Delete(ctx, "hello.txt")Secrets
Manage encrypted secrets stored per database; client calls never persist plaintext.
List secrets (metadata only)
Returns keys, purposes, and timestamps—no values.
secrets, err := db.OnyxSecrets().List(ctx)
fmt.Println(secrets, err)Fetch a secret value
Decrypts and returns the plaintext for a single key.
secret, err := db.OnyxSecrets().Get(ctx, "stripe_api_key")
fmt.Println(secret, err)Create or rotate a secret
Stores the value encrypted at rest; re-encrypts on each update.
err := db.OnyxSecrets().Set(ctx, onyx.OnyxSecret{
Key: "stripe_api_key",
Value: "sk_live_...",
Purpose: "Stripe server key",
})Delete a secret
Removes the record from the database.
err := db.OnyxSecrets().Delete(ctx, "stripe_api_key")Schema
Fetch, diff, validate, and publish schema revisions.
core := db.Core()
current, err := core.GetSchema(ctx, nil)
temp := onyx.Table{
Name: "TempTable",
Fields: []onyx.Field{
{Name: "id", Type: "String", Primary: true},
{Name: "name", Type: "String"},
},
}
schema := onyx.Schema{Tables: append(current.Tables, temp)}
err := core.ValidateSchema(ctx, schema)
err = core.PublishSchema(ctx, schema)