API Reference
Base URL: https://loremind.peekgames.dev/api/loremind/v1
Authentication
LoreMind uses API keys for server-to-server authentication. Keys are created in Projects under your project’s API Keys section.
| Key Type | Prefix | Use Case |
|---|---|---|
| Server Key | sk_server_ | Production server integration (NPC interactions) |
| Editor Key | sk_editor_ | Game engine editor tooling (Entity Minds, tags, scanner) |
Include your API key in the Authorization header:
Authorization: Bearer sk_server_your_key_hereNPC Interaction
POST /npc/interact
Generate an NPC response to player input. This is the primary endpoint for NPC interactions.
Authentication: Server Key (sk_server_*)
Request Body
{
// Required
text: string; // Player's message (max 10,000 chars)
entityMindId: string; // Entity Mind ID (provides name, personality, knowledge filters)
playerId: string; // Your player identifier (for rate limiting, memory, and conversation tracking)
// Optional
context?: {
location?: string; // Current location name
locationDetails?: string; // Location description
timeOfDay?: string; // "morning", "evening", etc.
weather?: string; // Weather conditions
npcMood?: string; // NPC's current mood
playerAppearance?: string; // How player looks to NPC
nearbyCharacters?: string[]; // Other characters present
recentEvents?: string[]; // Recent world events
};
memory?: {
retrieve?: boolean; // Retrieve past memories for this player (default: false)
};
activeKnowledgeTags?: string[]; // Narrow which lore the NPC can reference (by tag name)
conversationHistory?: Array<{
role: "user" | "assistant";
content: string;
}>;
}Response
{
success: true;
response: string; // NPC's response text
character: string; // Character name
metadata: {
memoryCheckpoint?: boolean; // True when session hit max length and memories were auto-saved
};
}Example Request
curl -X POST https://loremind.peekgames.dev/api/loremind/v1/npc/interact \
-H "Authorization: Bearer sk_server_your_key" \
-H "Content-Type: application/json" \
-d '{
"text": "What can you tell me about the dragon?",
"entityMindId": "em_abc123",
"playerId": "steam_76561198012345678",
"context": {
"location": "Blacksmith Shop",
"timeOfDay": "evening",
"weather": "rainy"
},
"memory": {
"retrieve": true
},
"activeKnowledgeTags": ["dragon-war", "village-history"]
}'Example Response
{
"success": true,
"response": "The dragon? Aye, I've heard the rumors. Spotted near the old watchtower, they say. If you're thinking of going after it, you'll need better steel than what you're carrying.",
"character": "Grom the Blacksmith",
"metadata": {}
}Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Missing or empty text | No player message provided |
| 400 | Text too long | Message exceeds 10,000 characters |
| 400 | Missing entityMindId | entityMindId is required |
| 400 | Missing playerId | playerId is required for API key authentication |
| 401 | Invalid API key | API key is missing, malformed, or revoked |
| 404 | Entity Mind not found | Invalid entityMindId |
| 402 | Insufficient credits | Team balance too low |
| 403 | Editor API keys cannot be used | Use Server Key, not Editor Key |
| 404 | Project not found | Invalid project or key |
| 429 | Rate limit exceeded | Too many requests (see Retry-After header) |
| 503 | Generation failed | LLM error (retry) |
Entity Minds
GET /lore/minds
List all Entity Minds for a project.
Authentication: Editor Key (sk_editor_*) or Dashboard session
Query Parameters:
projectId(required for dashboard users)
Response
{
minds: Array<{
id: string;
entityName: string;
personality: string;
backstory: string | null;
backstorySummary: string | null;
role: string | null;
speakingStyle: string | null;
hints: string[];
restrictions: string[];
locationId: string | null;
location: { id: string; name: string } | null;
knowledgeTags: string[];
knowledgeDescription: string;
computedFilter: object;
responseConfig: object;
buildCreditsUsed: number;
interactionCount: number;
relationshipCount: number;
createdAt: string;
updatedAt: string;
}>;
}Example (Game Engine Editor)
curl https://loremind.peekgames.dev/api/loremind/v1/lore/minds \
-H "Authorization: Bearer sk_editor_your_key"Tags
GET /lore/tags
List all tags for a project.
Authentication: Editor Key (sk_editor_*) or Dashboard session
Query Parameters:
projectId(required for dashboard users)
Response
{
success: true;
tags: Array<{
id: string;
name: string;
color: string | null;
isDefault: boolean;
documentCount: number;
}>;
defaultTags: Array<{ id: string; name: string; color: string | null; documentCount: number }>;
customTags: Array<{ id: string; name: string; color: string | null; documentCount: number }>;
totalCount: number;
}Lore Scanner
Scan game files for lore extraction. See Lore Scanner for a feature overview.
POST /scanner/estimate
Get a cost estimate from file metadata without uploading content.
Authentication: Editor Key (sk_editor_*) or Dashboard session
Request Body
{
files: Array<{
filename: string; // File name (e.g., "story.ink")
sizeBytes: number; // File size in bytes
}>;
}Response
{
estimatedMicrocredits: number;
estimatedCredits: number;
availableCredits: number; // Team's current credit balance
perFile: Array<{
filename: string;
estimatedMicrocredits: number;
}>;
}Example
curl -X POST https://loremind.peekgames.dev/api/loremind/v1/scanner/estimate \
-H "Authorization: Bearer sk_editor_your_key" \
-H "Content-Type: application/json" \
-d '{
"files": [
{ "filename": "story.ink", "sizeBytes": 45000 },
{ "filename": "npcs.json", "sizeBytes": 12000 }
]
}'Example Response
{
"estimatedMicrocredits": 57000,
"estimatedCredits": 57,
"availableCredits": 500,
"perFile": [
{ "filename": "story.ink", "estimatedMicrocredits": 45000 },
{ "filename": "npcs.json", "estimatedMicrocredits": 12000 }
]
}Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Missing projectId | projectId required (dashboard session only) |
| 400 | Invalid request | Invalid file metadata |
| 401 | Unauthorized | Missing or invalid authentication |
| 401 | Invalid authentication | JWT tokens not accepted |
| 404 | Project not found or access denied | Invalid project (dashboard session only) |
POST /scanner/submit
Upload game files for lore extraction. Returns 202 Accepted and processes in the background.
Authentication: Editor Key (sk_editor_*) or Dashboard session
Request Body (multipart/form-data)
files— Game data files (required, max 100 files)projectId— Project ID (required for dashboard session, ignored for editor key)idempotencyKey— Optional deduplication keyuserContext— Optional context about your game (helps the AI agent)
Response (202)
{
jobId: string;
status: "QUEUED";
totalFiles: number;
estimatedCredits: number;
rejected?: Array<{ name: string; error: string }>;
}Example
curl -X POST https://loremind.peekgames.dev/api/loremind/v1/scanner/submit \
-H "Authorization: Bearer sk_editor_your_key" \
-F "files=@story.ink" \
-F "files=@npcs.json" \
-F "userContext=A fantasy RPG set in the kingdom of Eldrath"Example Response
{
"jobId": "clx1abc123def456",
"status": "QUEUED",
"totalFiles": 2,
"estimatedCredits": 57
}Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Missing projectId | projectId required (dashboard session only) |
| 400 | No files provided | No files in the upload |
| 400 | No valid files | All files rejected (invalid type/size) |
| 401 | Unauthorized | Missing or invalid authentication |
| 402 | Insufficient credits | Not enough credits for estimated cost |
| 404 | Project not found or access denied | Invalid project (dashboard session only) |
GET /scanner/jobs
List scan jobs for a project.
Authentication: Editor Key (sk_editor_*) or Dashboard session
Query Parameters:
projectId(required for dashboard session, ignored for editor key)
Response
{
jobs: Array<{
jobId: string;
status: "QUEUED" | "PROCESSING" | "COMPLETED" | "FAILED";
totalFiles: number;
completedFiles: number;
failedFiles: number;
createdAt: string;
completedAt: string | null;
}>;
}Example
curl https://loremind.peekgames.dev/api/loremind/v1/scanner/jobs \
-H "Authorization: Bearer sk_editor_your_key"GET /scanner/jobs/{jobId}
Get the status and results of a scan job. Poll this endpoint to track progress.
Authentication: Editor Key (sk_editor_*) or Dashboard session
Response
{
jobId: string;
status: "QUEUED" | "PROCESSING" | "COMPLETED" | "FAILED";
totalFiles: number;
completedFiles: number;
failedFiles: number;
estimatedCredits: number;
actualCredits: number;
errorMessage: string | null;
createdAt: string;
startedAt: string | null;
completedAt: string | null;
extractions: Array<{
id: string;
title: string;
tags: string[];
location: string | null;
confidence: number;
contentPreview: string;
sourceFiles: string[];
}>;
skippedContent: Array<{
section: string;
reason: string;
sourceFile: string;
}>;
}Example
curl https://loremind.peekgames.dev/api/loremind/v1/scanner/jobs/clx1abc123def456 \
-H "Authorization: Bearer sk_editor_your_key"Error Responses
| Status | Error | Description |
|---|---|---|
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Access denied | Job belongs to a different project |
| 404 | Job not found | Invalid jobId |
POST /scanner/commit
Create Lore Documents from approved scan extractions. Returns 202 Accepted and processes embeddings in the background.
Authentication: Editor Key (sk_editor_*) or Dashboard session
Request Body
{
jobId: string;
extractionIds: string[]; // IDs of extractions to approve
}Response (202)
{
committed: number;
documentIds: string[];
}Example
curl -X POST https://loremind.peekgames.dev/api/loremind/v1/scanner/commit \
-H "Authorization: Bearer sk_editor_your_key" \
-H "Content-Type: application/json" \
-d '{
"jobId": "clx1abc123def456",
"extractionIds": ["ext_1", "ext_2", "ext_5"]
}'Example Response
{
"committed": 3,
"documentIds": ["doc_abc", "doc_def", "doc_ghi"]
}Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Invalid request | Missing jobId or empty extractionIds |
| 400 | Job is not completed yet | Job still processing |
| 400 | No matching extractions found | None of the IDs match |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Access denied | Job belongs to a different project |
| 404 | Job not found | Invalid jobId |
POST /scanner/rescan
Compare current file hashes against previous scans to identify changes (true-up).
Authentication: Editor Key (sk_editor_*) or Dashboard session
Request Body
{
files: Array<{
filename: string;
contentHash: string; // SHA-256 hash of file content
}>;
}Response
{
changed: string[]; // Files with different hash
added: string[]; // New files not in previous scan
deleted: string[]; // Files in previous scan but not in current
unchanged: string[]; // Files with same hash
}Example
curl -X POST https://loremind.peekgames.dev/api/loremind/v1/scanner/rescan \
-H "Authorization: Bearer sk_editor_your_key" \
-H "Content-Type: application/json" \
-d '{
"files": [
{ "filename": "story.ink", "contentHash": "a1b2c3..." },
{ "filename": "new_quest.ink", "contentHash": "d4e5f6..." }
]
}'Example Response
{
"changed": ["story.ink"],
"added": ["new_quest.ink"],
"deleted": ["old_quest.ink"],
"unchanged": []
}Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Invalid request | Invalid file metadata |
| 401 | Unauthorized | Missing or invalid authentication |
| 404 | Project not found or access denied | Invalid project (dashboard session only) |
Rate Limits
Rate limits are configurable per-project in Dashboard → Project Settings → Rate Limits.
Rate limits apply both per-player (using playerId) and per-project. Per-player limits prevent individual players from monopolizing resources, while per-project limits protect overall capacity.
Response Headers
When rate limited, the API returns:
Retry-After: Seconds until retry (included with 429 responses)
Credits
Credits are usage-based with no expiration. See Billing for pricing. Monitor your balance and usage in the dashboard .
When credits run low, requests return 402 Insufficient credits:
{
"error": "Insufficient credits",
"message": "This request requires approximately 0.45 credits. Current balance: 0.12.",
"creditsNeeded": 0.45,
"credits": 0.12
}SDK Integration
Game engine SDKs handle API calls automatically during editor testing. For production, you call the API from your backend - see Server Integration.
// In Editor: SDK uses Server API Key from Control Panel
// In Production: SDK routes through your backend URL
var npc = GetComponent<LoreMindNPC>();
var response = await npc.RespondAsync("Hello!");