GrayMatter API Reference
All GrayMatter operations are exposed through generated REST APIs with auto-generated SDKs for TypeScript, Python, and other clients.
Credit charges are calculated from the active runtime pricing matrix. Use this reference for API behavior, and use the main site Pricing page for current credit rates. Placeholder credit values in example payloads represent runtime-calculated numeric fields.
Base URL
https://api-0.valkyrlabs.com/v1
All endpoints require authentication via JWT bearer token:
Authorization: Bearer $JWT_TOKEN
Core Memory Operations
Create Memory Entry
Endpoint: POST /memory/entries
Create a new durable memory entry.
Request:
{
"type": "PREFERENCE",
"title": "Stripe API Integration Pattern",
"text": "Always use idempotency keys for payment mutations. Retry with exponential backoff on 429.",
"tags": ["payment", "stripe", "pattern"],
"metadata": {
"source": "lessons-learned",
"confidence": 0.95,
"domain": "fintech"
}
}
Response (201 Created):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "PREFERENCE",
"title": "Stripe API Integration Pattern",
"text": "Always use idempotency keys for payment mutations...",
"tags": ["payment", "stripe", "pattern"],
"metadata": {
"source": "lessons-learned",
"confidence": 0.95,
"domain": "fintech"
},
"principalId": "225e8400-e29b-41d4-a716-446655440099",
"createdAt": "2026-04-03T15:22:00Z",
"updatedAt": "2026-04-03T15:22:00Z",
"createdBy": "user@example.com"
}
Query Memory Entries
Endpoint: GET /memory/entries
Retrieve memory entries with flexible filtering.
Query Parameters:
| Parameter | Type | Default | Notes |
|---|---|---|---|
query | string | (required) | Keyword search across title and text |
tags | string[] | (empty) | Filter by tags (AND logic) |
type | string | (empty) | Filter by entry type: context, decision, artifact, configuration, preference, todo |
limit | integer | 20 | Max 100 results per page |
offset | integer | 0 | Pagination offset |
sort | string | updatedAt | Sort by: createdAt, updatedAt, relevance |
order | string | DESC | ASC or DESC |
Example:
GET /memory/entries?query=payment&tags=stripe&tags=pattern&type=PREFERENCE&limit=10
Response (200 OK):
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "PREFERENCE",
"title": "Stripe API Integration Pattern",
"text": "Always use idempotency keys...",
"tags": ["payment", "stripe", "pattern"],
"createdAt": "2026-04-03T15:22:00Z",
"relevanceScore": 0.97
}
],
"total": 1,
"limit": 10,
"offset": 0
}
Get Memory Entry
Endpoint: GET /memory/entries/{id}
Retrieve a single memory entry by ID.
Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "PREFERENCE",
"title": "Stripe API Integration Pattern",
"text": "Always use idempotency keys for payment mutations...",
"tags": ["payment", "stripe", "pattern"],
"metadata": {
"source": "lessons-learned",
"confidence": 0.95,
"domain": "fintech"
},
"principalId": "225e8400-e29b-41d4-a716-446655440099",
"createdAt": "2026-04-03T15:22:00Z",
"updatedAt": "2026-04-03T15:22:00Z",
"createdBy": "user@example.com"
}
Update Memory Entry
Endpoint: PATCH /memory/entries/{id}
Update an existing memory entry. Only provided fields are updated.
Request:
{
"text": "Always use idempotency keys for payment mutations. Retry with exponential backoff (2^n * 100ms) on 429.",
"metadata": {
"source": "lessons-learned",
"confidence": 0.98,
"lastReviewedDate": "2026-04-03"
}
}
Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "PREFERENCE",
"title": "Stripe API Integration Pattern",
"text": "Always use idempotency keys for payment mutations. Retry with exponential backoff (2^n * 100ms) on 429.",
"tags": ["payment", "stripe", "pattern"],
"metadata": {
"source": "lessons-learned",
"confidence": 0.98,
"lastReviewedDate": "2026-04-03"
},
"updatedAt": "2026-04-03T16:45:00Z"
}
Credit charge: Runtime configured; see Pricing.
Delete Memory Entry
Endpoint: DELETE /memory/entries/{id}
Soft-delete a memory entry (marked as retired, not physically removed).
Response (204 No Content)
Credit charge: Runtime configured; see Pricing.
Operational Endpoints
Memory Statistics
Endpoint: GET /memory/stats
Retrieve operational metrics and health signals.
Response (200 OK):
{
"context": {
"usedPct": 0.73,
"relevantPct": 0.88,
"wastePct": 0.12
},
"memory": {
"hitRate": 0.92,
"totalEntries": 1247,
"hotEntries": 156,
"coldEntries": 234
},
"cost": {
"lastRun": 2.5,
"waste": 18.2,
"burnRate": 42.5,
"retrievalCost": 125.3,
"writesCost": 87.2,
"assemblyCost": 34.8
},
"alerts": [
{
"severity": "WARNING",
"message": "Context utilization above 70%. Consider compacting.",
"recommendedAction": "COMPACT"
}
],
"recommendations": [
{
"action": "COMPACT",
"rationale": "73% utilization; estimated 8% space recovery",
"estimatedCredits": "<runtime-calculated>"
}
],
"sampledAt": "2026-04-03T16:50:00Z"
}
Credit charge: Runtime configured; see Pricing.
Memory Runs
Endpoint: GET /memory/runs?limit=20
Retrieve recent memory operations (compact, reindex, prune, expand).
Query Parameters:
| Parameter | Type | Default | Notes |
|---|---|---|---|
limit | integer | 20 | Max 100; min 1 |
Response (200 OK):
{
"runs": [
{
"id": "run-220404-001",
"action": "COMPACT",
"initiatedAt": "2026-04-02T22:15:00Z",
"completedAt": "2026-04-02T22:16:30Z",
"durationMs": 90000,
"entriesProcessed": 1247,
"spaceRecoveredMb": 84.3,
"creditsCharged": "<runtime-calculated>",
"success": true
},
{
"id": "run-220404-002",
"action": "REINDEX",
"initiatedAt": "2026-04-02T18:10:00Z",
"completedAt": "2026-04-02T18:25:45Z",
"durationMs": 945000,
"entriesProcessed": 1247,
"creditsCharged": "<runtime-calculated>",
"indexStatus": "HEALTHY",
"success": true
}
],
"total": 2
}
Memory Actions
Compact
Endpoint: POST /memory/compact
Consolidate and optimize memory storage. Removes redundancy, deduplicates similar entries, and frees space.
Request:
{
"dryRun": false
}
Response (200 OK):
{
"action": "COMPACT",
"success": true,
"durationMs": 85000,
"entriesProcessed": 1247,
"spaceRecoveredMb": 82.5,
"creditsCharged": "<runtime-calculated>",
"updatedStats": {
"context": {
"usedPct": 0.68,
"relevantPct": 0.91,
"wastePct": 0.09
},
"memory": {
"hitRate": 0.94,
"totalEntries": 1223
}
}
}
Credit charge: Runtime configured; dryRun == true does not charge when supported.
Reindex
Endpoint: POST /memory/reindex
Rebuild semantic indexes to improve retrieval quality.
Request:
{
"dryRun": false,
"strategy": "FULL" // FULL or INCREMENTAL
}
Response (200 OK):
{
"action": "REINDEX",
"success": true,
"durationMs": 920000,
"entriesProcessed": 1247,
"creditsCharged": "<runtime-calculated>",
"indexMetrics": {
"vectorDimensionality": 1536,
"indexHealth": 0.99,
"retrievalQualityDelta": 0.03
},
"updatedStats": {
"memory": {
"hitRate": 0.95,
"retrievalLatencyMs": 45
}
}
}
Credit charge: Runtime configured; dryRun == true does not charge when supported.
Prune
Endpoint: POST /memory/prune
Remove stale, low-signal, or low-confidence entries.
Request:
{
"dryRun": false,
"confidenceThreshold": 0.5,
"unusedDaysThreshold": 180
}
Response (200 OK):
{
"action": "PRUNE",
"success": true,
"entriesDeleted": 124,
"creditsCharged": "<runtime-calculated>",
"deletionReasons": {
"lowConfidence": 57,
"staleAndUnused": 67
},
"updatedStats": {
"memory": {
"totalEntries": 1123,
"hitRate": 0.93
}
}
}
Credit charge: Runtime configured; dryRun == true does not charge when supported.
Expand
Endpoint: POST /memory/expand
Increase memory capacity when demand is sustained.
Request:
{
"dryRun": false,
"capacityIncrementMb": 100
}
Response (200 OK):
{
"action": "EXPAND",
"success": true,
"previousCapacityMb": 500,
"newCapacityMb": 600,
"creditsCharged": "<runtime-calculated>",
"updatedStats": {
"context": {
"usedPct": 0.61
}
}
}
Credit charge: Runtime configured per capacity increment.
TypeScript SDK Usage
Installation
npm install @valkyr-labs/api-client
Query Memory
import { MemoryEntryService } from "@valkyr-labs/api-client";
const service = new MemoryEntryService({
baseUrl: "https://api-0.valkyrlabs.com/v1",
token: process.env.JWT_TOKEN,
});
// Query memory with filters
const results = await service.queryEntries({
query: "payment",
tags: ["stripe", "pattern"],
type: "PREFERENCE",
limit: 10,
});
console.log(`Found ${results.total} memories`);
results.items.forEach((entry) => {
console.log(`- ${entry.title} (confidence: ${entry.metadata.confidence})`);
});
Create Memory
const newEntry = await service.createEntry({
type: "preference",
title: "Always validate webhook signatures",
text: "Verify HMAC-SHA256 signature on all incoming webhooks using the shared secret.",
tags: ["webhook", "security", "payment"],
metadata: {
source: "security-audit",
confidence: 0.99,
},
});
console.log(`Created memory: ${newEntry.id}`);
Watch Memory Stats
const stats = await service.getMemoryStats();
console.log(`Hit rate: ${(stats.memory.hitRate * 100).toFixed(1)}%`);
console.log(
`Context utilization: ${(stats.context.usedPct * 100).toFixed(1)}%`,
);
if (stats.alerts.length > 0) {
console.warn(
"Alerts:",
stats.alerts.map((a) => a.message),
);
}
// Execute recommended actions
for (const rec of stats.recommendations) {
if (rec.action === "COMPACT") {
const result = await service.compact({ dryRun: false });
console.log(
`Compact successful; space recovered: ${result.spaceRecoveredMb}MB`,
);
}
}
Error Handling
HTTP Status Codes
| Code | Meaning | Action |
|---|---|---|
| 200 | Success | Operation completed |
| 201 | Created | New resource created |
| 204 | No Content | Deletion successful |
| 400 | Bad Request | Invalid parameters; see error.details |
| 401 | Unauthorized | Missing or invalid JWT token |
| 403 | Forbidden | Insufficient permissions or quota |
| 404 | Not Found | Resource not found |
| 402 | Payment Required | Insufficient credits |
| 429 | Too Many Requests | Rate limited; retry with backoff |
| 500 | Server Error | Unexpected error; contact support |
Error Response
{
"error": "INSUFFICIENT_CREDITS",
"message": "Cannot execute REINDEX: insufficient credits for the current pricing matrix",
"code": 402,
"details": {
"required": "<runtime-calculated>",
"available": "<current-balance>",
"action": "REINDEX"
}
}
Rate Limiting
GrayMatter enforces per-account rate limits:
- Reads: 1,000 per minute
- Writes: 100 per minute
- Compact/Reindex/Prune: 5 per hour
- Expand: 1 per hour
Rate limit headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 923
X-RateLimit-Reset: 1712151600
Retry with exponential backoff (2^n * 100ms) when hitting 429.
Idempotency
All write operations support idempotency keys for safe replay:
POST /memory/entries \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{...}'
If the same key is used twice, the second request returns the result of the first without creating a duplicate.
Webhooks (Coming Soon)
GrayMatter will support webhooks for:
memory.entry.createdmemory.entry.updatedmemory.entry.deletedmemory.stats.alert
Register webhooks via /webhook/subscribe endpoint.