GrayMatter Quick Reference Card
Authentication
All requests require JWT token in Authorization header:
Authorization: Bearer eyJhbGc...
For agents and operators using the GrayMatter plugin, prefer the managed login flow instead of manually pasting tokens:
scripts/gm-login
scripts/gm-install-check
scripts/gm-doctor --quick
gm-login stores reusable auth in the OS keychain when available. gm-doctor --quick verifies install health, auth, memory layer, business graph layer, OpenAPI cache, MCP contract, and deferred replay without running the credit-consuming smoke query.
From the ValkyrAI repository, run the bridge wrapper instead:
scripts/graymatter-doctor.sh --quick
Core Endpoints
Credit charges are runtime-configured. Use this page for endpoint shape, and use the main site Pricing page for current credit pricing.
Memory CRUD
| Operation | Endpoint | Method | Credit Charge |
|---|---|---|---|
| Create | /v1/memory/entries | POST | Runtime configured |
| Read | /v1/memory/entries/{id} | GET | Runtime configured |
| Query | /v1/memory/entries?query=X | GET | Runtime configured |
| Update | /v1/memory/entries/{id} | PATCH | Runtime configured |
| Delete | /v1/memory/entries/{id} | DELETE | Runtime configured |
Operations
| Operation | Endpoint | Method | Credit Charge |
|---|---|---|---|
| Stats | /v1/memory/stats | GET | Runtime configured |
| Runs | /v1/memory/runs | GET | Runtime configured |
| Compact | /v1/memory/compact | POST | Runtime configured |
| Reindex | /v1/memory/reindex | POST | Runtime configured |
| Prune | /v1/memory/prune | POST | Runtime configured |
| Expand | /v1/memory/expand | POST | Runtime configured |
TypeScript SDK Quick Start
Installation
npm install @valkyr-labs/api-client
Create Entry
const memory = new MemoryEntryService({ token });
const entry = await memory.createEntry({
type: "preference",
title: "My Pattern",
text: "Description here",
tags: ["tag1", "tag2"],
metadata: { key: "value" },
});
Query Entries
const results = await memory.queryEntries({
query: "search term",
tags: ["tag1"],
type: "preference",
limit: 10,
});
results.items.forEach((item) => {
console.log(item.title);
});
Get Single Entry
const entry = await memory.getEntry("entry-id");
Update Entry
const updated = await memory.updateEntry("entry-id", {
text: "Updated text",
metadata: { newField: "value" },
});
Delete Entry
await memory.deleteEntry("entry-id");
Watch Stats
const stats = await memory.getMemoryStats();
console.log(`Hit rate: ${stats.memory.hitRate}`);
console.log(`Utilization: ${stats.context.usedPct}`);
Run Operations
// Compact
const compact = await memory.compact({ dryRun: false });
console.log(`Space recovered: ${compact.spaceRecoveredMb}MB`);
// Reindex
const reindex = await memory.reindex({ dryRun: false });
console.log(`Reindex complete`);
// Prune
const prune = await memory.prune({
confidenceThreshold: 0.5,
dryRun: false,
});
console.log(`Deleted: ${prune.entriesDeleted}`);
Python HTTP Quick Start
Create Entry
import os
import requests
base_url = os.environ.get("VALKYRAI_API_URL", "http://localhost:8080/v1")
headers = {"Authorization": f"Bearer {os.environ['JWT_TOKEN']}"}
entry = requests.post(
f"{base_url}/memory/entries",
headers=headers,
json={
"type": "instruction",
"text": "Description here",
"tags": ["tag1", "tag2"],
},
).json()
Query Entries
results = requests.get(
f"{base_url}/memory/entries",
headers=headers,
params={"query": "search term", "tags": "tag1", "type": "instruction", "limit": 10},
).json()
for item in results:
print(item.title)
Memory Operations
# Compact
compact = requests.post(f"{base_url}/memory/compact", headers=headers, json={"dryRun": False}).json()
print(compact)
# Reindex
reindex = requests.post(f"{base_url}/memory/reindex", headers=headers, json={"dryRun": False}).json()
print(reindex)
# Prune
prune = requests.post(f"{base_url}/memory/prune", headers=headers, json={"dryRun": False}).json()
print(prune)
Query Syntax Examples
# Simple keyword
GET /v1/memory/entries?query=payment
# Multiple tags (AND)
GET /v1/memory/entries?query=payment&tags=stripe&tags=pattern
# Full-text search
GET /v1/memory/entries?query=exponential%20backoff
# Type filter
GET /v1/memory/entries?query=retry&type=preference
# Sorting
GET /v1/memory/entries?query=payment&sort=updatedAt&order=DESC
# Pagination
GET /v1/memory/entries?query=payment&limit=20&offset=40
Error Codes & Fixes
| Code | Error | Fix |
|---|---|---|
| 400 | Bad Request | Check query parameters |
| 401 | Unauthorized | Verify JWT token is valid |
| 402 | Payment Required | Purchase credits at /buy-credits |
| 403 | Forbidden | Check ACL permissions |
| 404 | Not Found | Verify entry ID is correct |
| 429 | Too Many Requests | Retry with backoff (2^n * 100ms) |
| 500 | Server Error | Contact support |
CLI Recovery Commands
| Situation | Command |
|---|---|
| Fresh install or first auth | scripts/gm-activate |
| Need a complete readiness report | scripts/gm-doctor --quick |
| Need the same report from ValkyrAI | scripts/graymatter-doctor.sh --quick |
| Need live write/query proof | scripts/gm-doctor |
| Token missing or expired | scripts/gm-login && scripts/gm-install-check |
| Plugin feels stale | scripts/gm-self-update maybe |
| OpenAPI/schema looks stale | scripts/gm-openapi-sync && scripts/gm-openapi-summary |
| Writes were deferred during an outage | scripts/gm-replay-deferred |
Query fails with 402 | Recharge credits, then rerun scripts/gm-doctor |
Rate Limits
| Resource | Limit |
|---|---|
| Reads/min | 1,000 |
| Writes/min | 100 |
| Compact/hour | 5 |
| Reindex/hour | 3 |
| Prune/hour | 5 |
Memory Types
| Type | Purpose | Example |
|---|---|---|
| context | Reusable operational or domain context | "SAP has 28% market share" |
| decision | Chosen direction and rationale | "Use hosted embeddings for production retrieval" |
| artifact | Outputs, results | "Generated pitch deck JSON" |
| configuration | Durable system or agent configuration notes | "ValorIDE uses api-0 as its default ValkyrAI host" |
| preference | User/agent preferences | "Always use exponential backoff" |
| todo | Follow-up work that should survive sessions | "Reindex after importing customer history" |
Entry Structure
{
"id": "uuid",
"type": "context|decision|artifact|configuration|preference|todo",
"title": "Human-readable title",
"text": "Full content",
"tags": ["tag1", "tag2"],
"metadata": {
"key1": "value1",
"confidence": 0.95,
"source": "origin"
},
"principalId": "owner-uuid",
"createdAt": "2026-04-03T15:22:00Z",
"updatedAt": "2026-04-03T15:22:00Z",
"createdBy": "user@example.com"
}
Monitoring Commands
# Check stats every hour
watch -n 3600 'curl -H "Authorization: Bearer $TOKEN" https://api-0.valkyrlabs.com/v1/memory/stats | jq'
# Monitor burst rate
curl https://api-0.valkyrlabs.com/v1/memory/stats | jq '.cost.burnRate'
# List recent operations
curl https://api-0.valkyrlabs.com/v1/memory/runs?limit=10 | jq '.runs[] | {action, success, creditsCharged}'
# Check credit balance
curl https://api-0.valkyrlabs.com/v1/credits/{accountId}/balance | jq '.balance'
Common Patterns
Pre-Task Context Reading
const context = await memory.queryEntries({
query: taskGoal,
tags: ["instruction"],
limit: 5,
});
// Use context in execution
Post-Task Learning Capture
await memory.createEntry({
type: "decision",
title: `Success: ${taskName}`,
text: resultSummary,
tags: ["learned", taskType],
metadata: { success: true, duration: ms },
});
Conditional Branching
const rules = await memory.queryEntries({
query: decisionPoint,
type: "PREFERENCE",
limit: 1,
});
const decision = interpretRule(rules.items[0]);
Multi-Agent Coordination
// Agent 1: Write findings
await memory.createEntry({
text: findings,
tags: ["shared", "research"],
});
// Agent 2: Read & extend
const prior = await memory.queryEntries({
tags: ["shared", "research"],
});
const extended = extend(prior, newAnalysis);
Dashboard URLs
- Memory Dashboard:
/graymatter-memory - Credits:
/credits/{accountId} - Buy Credits:
/buy-credits
Support & Docs
- Full API Reference: See API Docs
- Developer Guide: See Developer Guide
- Operational Guide: See Playbook
- Use Cases: See Real-World Examples
- Troubleshooting: See FAQ