Skip to main content

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:

ParameterTypeDefaultNotes
querystring(required)Keyword search across title and text
tagsstring[](empty)Filter by tags (AND logic)
typestring(empty)Filter by entry type: context, decision, artifact, configuration, preference, todo
limitinteger20Max 100 results per page
offsetinteger0Pagination offset
sortstringupdatedAtSort by: createdAt, updatedAt, relevance
orderstringDESCASC 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:

ParameterTypeDefaultNotes
limitinteger20Max 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

CodeMeaningAction
200SuccessOperation completed
201CreatedNew resource created
204No ContentDeletion successful
400Bad RequestInvalid parameters; see error.details
401UnauthorizedMissing or invalid JWT token
403ForbiddenInsufficient permissions or quota
404Not FoundResource not found
402Payment RequiredInsufficient credits
429Too Many RequestsRate limited; retry with backoff
500Server ErrorUnexpected 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.created
  • memory.entry.updated
  • memory.entry.deleted
  • memory.stats.alert

Register webhooks via /webhook/subscribe endpoint.