Skip to Content

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 TypePrefixUse Case
Server Keysk_server_Production server integration (NPC interactions)
Editor Keysk_editor_Game engine editor tooling (Entity Minds, tags, scanner)

Include your API key in the Authorization header:

Authorization: Bearer sk_server_your_key_here

NPC 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

StatusErrorDescription
400Missing or empty textNo player message provided
400Text too longMessage exceeds 10,000 characters
400Missing entityMindIdentityMindId is required
400Missing playerIdplayerId is required for API key authentication
401Invalid API keyAPI key is missing, malformed, or revoked
404Entity Mind not foundInvalid entityMindId
402Insufficient creditsTeam balance too low
403Editor API keys cannot be usedUse Server Key, not Editor Key
404Project not foundInvalid project or key
429Rate limit exceededToo many requests (see Retry-After header)
503Generation failedLLM 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

StatusErrorDescription
400Missing projectIdprojectId required (dashboard session only)
400Invalid requestInvalid file metadata
401UnauthorizedMissing or invalid authentication
401Invalid authenticationJWT tokens not accepted
404Project not found or access deniedInvalid 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 key
  • userContext — 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

StatusErrorDescription
400Missing projectIdprojectId required (dashboard session only)
400No files providedNo files in the upload
400No valid filesAll files rejected (invalid type/size)
401UnauthorizedMissing or invalid authentication
402Insufficient creditsNot enough credits for estimated cost
404Project not found or access deniedInvalid 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

StatusErrorDescription
401UnauthorizedMissing or invalid authentication
403Access deniedJob belongs to a different project
404Job not foundInvalid 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

StatusErrorDescription
400Invalid requestMissing jobId or empty extractionIds
400Job is not completed yetJob still processing
400No matching extractions foundNone of the IDs match
401UnauthorizedMissing or invalid authentication
403Access deniedJob belongs to a different project
404Job not foundInvalid 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

StatusErrorDescription
400Invalid requestInvalid file metadata
401UnauthorizedMissing or invalid authentication
404Project not found or access deniedInvalid 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!");
Last updated on