{"openapi":"3.1.0","info":{"title":"newcharactersheet.com API","version":"1.0.0","description":"Generate and manage AI character reference sheets and scenes. API usage defaults to account credits; authenticate with an API key via the X-API-Key header."},"servers":[{"url":"https://newcharactersheet.com","description":"Production"}],"security":[{"ApiKeyAuth":[]}],"x-rateLimits":{"production":true,"globalReadPerMinutePerIp":2000,"globalWritePerMinutePerIp":300,"generationPerMinutePerIp":10,"apiKeyDailyQuota":1000},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key prefixed with ncs_. Generate one from Settings or POST /api/api-keys."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}},"WorkflowGraphDraft":{"type":"object","description":"Validated workflow graph draft. This wraps the existing workflow JSON execution format.","properties":{"name":{"type":"string"},"description":{"type":"string"},"nodes":{"type":"array","items":{"type":"object","additionalProperties":true}},"edges":{"type":"array","items":{"type":"object","additionalProperties":true}},"metadata":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"string"}}},"required":["name","nodes","edges"]},"WorkflowValidationResult":{"type":"object","properties":{"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object","additionalProperties":true}},"warnings":{"type":"array","items":{"type":"object","additionalProperties":true}},"info":{"type":"array","items":{"type":"object","additionalProperties":true}},"autoFixes":{"type":"array","items":{"type":"object","additionalProperties":true}},"runBlockers":{"type":"array","items":{"type":"object","additionalProperties":true}},"graph":{"$ref":"#/components/schemas/WorkflowGraphDraft"}},"required":["valid","errors","warnings","info","autoFixes","runBlockers","graph"]},"SheetImage":{"type":"object","properties":{"storagePath":{"type":"string"},"publicUrl":{"type":"string","format":"uri"},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"}}},"SheetVideo":{"type":"object","properties":{"storagePath":{"type":"string"},"publicUrl":{"type":"string","format":"uri"},"contentType":{"type":"string"}}},"PanelCut":{"type":"object","properties":{"id":{"type":"string"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":0,"maximum":1},"height":{"type":"number","minimum":0,"maximum":1}}},"Sheet":{"type":"object","properties":{"id":{"type":"string"},"ownerUid":{"type":"string"},"sheetType":{"type":"string","enum":["character","scene"]},"visibility":{"type":"string","enum":["public","private"]},"prompt":{"type":"string"},"keywords":{"type":"array","items":{"type":"string"}},"handle":{"type":"string"},"createdAt":{"type":"integer"},"updatedAt":{"type":"integer"},"image":{"$ref":"#/components/schemas/SheetImage"},"video":{"$ref":"#/components/schemas/SheetVideo"},"accessUrl":{"type":"string","format":"uri","description":"Resolved image URL (signed for private, public for public)"},"videoAccessUrl":{"type":"string","format":"uri"},"feedVideoUrl":{"type":"string","format":"uri","description":"Short-form feed video URL"},"feedPosterUrl":{"type":"string","format":"uri","description":"Feed video poster image URL"},"panelCuts":{"type":"array","items":{"$ref":"#/components/schemas/PanelCut"}},"stats":{"type":"object","properties":{"savesCount":{"type":"integer"},"likesCount":{"type":"integer"},"commentsCount":{"type":"integer"}}},"project":{"type":"object","description":"Project this sheet belongs to","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"savedFrom":{"type":"object","description":"Source sheet if this is a remix/save","properties":{"sheetId":{"type":"string"},"ownerUid":{"type":"string"}}},"characterRefs":{"type":"array","items":{"type":"string"},"description":"Sheet IDs of characters referenced in this scene"},"viewerHasLiked":{"type":"boolean","description":"Whether the authenticated viewer has liked this sheet"}}},"GenerateResult":{"type":"object","properties":{"id":{"type":"string","description":"ID of the created sheet. Fetch full sheet via GET /api/sheets/{id}."}}},"ApiKeyInfo":{"type":"object","properties":{"keyId":{"type":"string"},"label":{"type":"string"},"last4":{"type":"string"},"createdAt":{"type":"integer"}}},"CreditTransaction":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["purchase","spend","refund","bonus","subscription_reset","subscription_grant"]},"amount":{"type":"number"},"balance":{"type":"number"},"description":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"createdAt":{"type":"integer"}}},"CreditBalance":{"type":"object","description":"New accounts receive 300 welcome credits by default. Subscription credits reset each billing cycle; top-up credits do not expire.","properties":{"balance":{"type":"number"},"subscriptionCredits":{"type":"number"},"topUpCredits":{"type":"number"},"tier":{"type":"string"},"totalPurchased":{"type":"number"},"totalSpent":{"type":"number"},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/CreditTransaction"}}}},"BillingSettings":{"type":"object","properties":{"mode":{"type":"string","enum":["CREDITS","BYO","MANAGED"]},"managedPlanAvailable":{"type":"boolean"},"creditsAvailable":{"type":"boolean"},"platformProviders":{"type":"array","items":{"type":"string"}},"hasByoApiKey":{"type":"boolean"},"byoApiKeyHint":{"type":"string","nullable":true},"availableProviders":{"type":"array","items":{"type":"object","additionalProperties":true}},"providerKeys":{"type":"object","additionalProperties":true},"imageProvider":{"type":"string"},"videoProvider":{"type":"string"},"usage":{"type":"object","properties":{"minuteCount":{"type":"integer"},"dayCount":{"type":"integer"},"monthCount":{"type":"integer"},"dayKey":{"type":"string"},"monthKey":{"type":"string"}}},"managedSpend":{"type":"object","additionalProperties":true}}}}},"paths":{"/api/auth/me":{"get":{"operationId":"getMe","summary":"Get current authenticated user","tags":["Auth"],"responses":{"200":{"description":"Authentication status","content":{"application/json":{"schema":{"type":"object","properties":{"authenticated":{"type":"boolean"},"uid":{"type":"string"}},"required":["authenticated"]}}}}}}},"/api/credits/balance":{"get":{"operationId":"getCreditBalance","summary":"Get credit balance and recent transactions","description":"Credit mode is the default billing model when platform providers are available. Current costs: images 10/12/25 credits by model tier, audio from 5 credits, videos 50/100/200/400 credits by model tier, 3D models 150 credits. A few specialty models carry custom per-model pricing above their tier; the per-generation cost shown in the app is authoritative.","tags":["Billing & Credits"],"responses":{"200":{"description":"Credit balance and recent transaction history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditBalance"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/billing":{"get":{"operationId":"getBillingSettings","summary":"Get billing mode and provider availability","tags":["Billing & Credits"],"responses":{"200":{"description":"Billing settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSettings"}}}}}},"put":{"operationId":"updateBillingSettings","summary":"Switch billing mode or save a provider key","description":"Use CREDITS for account credits, or BYO to use saved provider keys. Saving a provider key switches the account to BYO mode.","tags":["Billing & Credits"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["CREDITS","BYO","MANAGED"]},"providerName":{"type":"string"},"apiKey":{"type":"string"},"activeFor":{"type":"array","items":{"type":"string","enum":["image","video","audio"]}}}}}}},"responses":{"200":{"description":"Updated billing settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSettings"}}}},"400":{"description":"Invalid billing mode or provider key payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/credits/checkout":{"post":{"operationId":"createCreditCheckoutSession","summary":"Create a Stripe checkout session for credit top-ups","tags":["Billing & Credits"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"packageId":{"type":"string","enum":["starter","creator","studio","enterprise"]},"returnPath":{"type":"string","default":"/settings"}},"required":["packageId"]}}}},"responses":{"200":{"description":"Stripe checkout URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}}}}}},"503":{"description":"Stripe or selected credit package is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/generate":{"post":{"operationId":"generateCharacterSheet","summary":"Generate a character reference sheet","description":"Accepts multipart/form-data. In CREDITS mode, image generation usually costs 12 credits and may be lower or higher by model tier. Credits are refunded if generation fails. Prompt max 10,000 characters; files max 50 MB each and 100 MB total.","tags":["Generation"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"prompt":{"type":"string","description":"Character description prompt"},"keywords":{"type":"string","description":"Comma-separated keywords"},"visibility":{"type":"string","enum":["public","private"],"default":"private"},"style":{"type":"string","description":"Art style"},"referenceImages":{"type":"array","items":{"type":"string","format":"binary"},"description":"Reference images for the character"},"projectMode":{"type":"string","enum":["new","existing"],"description":"Attach the generated sheet to a project"},"projectId":{"type":"string","description":"Existing project ID when projectMode is existing"},"projectName":{"type":"string","description":"New project name when projectMode is new"},"folderId":{"type":"string","description":"Folder to place the generated sheet in"}},"required":["prompt"]}}}},"responses":{"201":{"description":"Character sheet generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateResult"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits, missing provider key, or free quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Generation routes allow 10 requests per minute per IP; API keys allow 1,000 requests per day by default.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sheets/{id}":{"get":{"operationId":"getSheet","summary":"Get a character sheet by ID","tags":["Sheets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Sheet details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sheet"}}}},"404":{"description":"Sheet not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateSheet","summary":"Update sheet keywords, handle, or character refs","tags":["Sheets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"keywords":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"string"}]},"handle":{"type":"string","nullable":true},"characterRefs":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Updated sheet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sheet"}}}}}},"delete":{"operationId":"deleteSheet","summary":"Delete a sheet you own","tags":["Sheets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sheets/search":{"get":{"operationId":"searchSheets","summary":"Search character sheets","tags":["Sheets"],"parameters":[{"name":"q","in":"query","description":"Search query","schema":{"type":"string"}}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"prompt":{"type":"string"},"keywords":{"type":"array","items":{"type":"string"}},"handle":{"type":"string"},"imageUrl":{"type":"string","format":"uri"}}}}}}}}}}}},"/api/visibility/{id}":{"patch":{"operationId":"updateVisibility","summary":"Change sheet visibility","tags":["Sheets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"visibility":{"type":"string","enum":["public","private"]}},"required":["visibility"]}}}},"responses":{"200":{"description":"Updated sheet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sheet"}}}}}}},"/api/scene/generate":{"post":{"operationId":"generateScene","summary":"Generate a scene image featuring characters","description":"Creates a saved scene image. Scene feature access is still account-gated; when the account uses CREDITS mode, image generation usually costs 12 credits and refunds on failure.","tags":["Scenes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","description":"Scene description"},"sheetIds":{"type":"array","items":{"type":"string"},"description":"Character sheet IDs to include in the scene (max 8)","maxItems":8},"outputMode":{"type":"string","enum":["picture","video"],"description":"Compatibility flag. This endpoint saves a scene image; video workflows use dedicated video routes.","default":"picture"},"projectMode":{"type":"string","enum":["new","existing"]},"existingProjectId":{"type":"string"},"projectName":{"type":"string"},"cinematicControls":{"type":"object","additionalProperties":true}}}}}},"responses":{"201":{"description":"Scene generated","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"imageBase64":{"type":"string"},"contentType":{"type":"string"},"outputMode":{"type":"string"}}}}}},"402":{"description":"Insufficient credits or free quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scene feature access required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/scene/video-preview":{"post":{"operationId":"generateSceneVideo","summary":"Generate a scene video","description":"Direct video generation endpoint. In CREDITS mode, video generation costs 50, 100, 200, or 400 credits by model tier. Some providers return a pending providerJob; send the same providerJob in a follow-up request to resume polling without another charge.","tags":["Scenes","Generation"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","description":"Video prompt"},"sheetIds":{"type":"array","items":{"type":"string"},"description":"Character sheet IDs to reference (max 8)","maxItems":8},"sceneIds":{"type":"array","items":{"type":"string"},"description":"Scene sheet IDs to reference (max 4)","maxItems":4},"firstImageId":{"type":"string","description":"Sheet ID to use as first frame"},"lastImageId":{"type":"string","description":"Sheet ID to use as last frame for interpolation"},"firstFrameImage":{"type":"object","additionalProperties":true,"description":"Inline first-frame image payload"},"lastFrameImage":{"type":"object","additionalProperties":true,"description":"Inline last-frame image payload"},"aspectRatio":{"type":"string"},"durationSeconds":{"type":"number","minimum":1,"maximum":30},"resolution":{"type":"string"},"negativePrompt":{"type":"string"},"seed":{"type":"number"},"generateAudio":{"type":"boolean"},"numberOfVideos":{"type":"number","minimum":1,"maximum":4},"modelOverride":{"type":"string","description":"Video model ID to use"},"cinematicControls":{"type":"object","additionalProperties":true},"providerJob":{"type":"object","additionalProperties":true,"description":"Pending provider job returned by a previous request"}}}}}},"responses":{"200":{"description":"Completed video or pending provider job","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"videoUrl":{"type":"string","format":"uri"},"contentType":{"type":"string"},"sourceUri":{"type":"string","nullable":true},"videos":{"type":"array","items":{"type":"object","properties":{"videoUrl":{"type":"string","format":"uri"},"contentType":{"type":"string"},"sourceUri":{"type":"string","nullable":true}}}},"textResponse":{"type":"string"}}},{"type":"object","properties":{"pending":{"type":"boolean","const":true},"providerName":{"type":"string"},"providerJob":{"type":"object","additionalProperties":true}},"required":["pending","providerName","providerJob"]}]}}}},"402":{"description":"Insufficient credits or free video quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scene/video feature access required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/workflows/compile":{"post":{"operationId":"compileWorkflowDraft","summary":"Compile user intent into a validated workflow graph draft","tags":["Workflow Agents"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"intent":{"type":"string"},"currentWorkflow":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"nodes":{"type":"array","items":{"type":"object","additionalProperties":true}},"edges":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"preferences":{"type":"object","properties":{"imageModel":{"type":"string"},"videoModel":{"type":"string"},"aspectRatio":{"type":"string"}}},"assets":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["intent"]}}}},"responses":{"200":{"description":"Compiled graph draft plus validation and explanation groups. This endpoint does not save.","content":{"application/json":{"schema":{"type":"object","properties":{"draft":{"$ref":"#/components/schemas/WorkflowGraphDraft"},"validation":{"$ref":"#/components/schemas/WorkflowValidationResult"},"explanation":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}}}},"/api/workflows/validate":{"post":{"operationId":"validateWorkflowDraft","summary":"Validate a workflow graph draft without saving it","tags":["Workflow Agents"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"draft":{"$ref":"#/components/schemas/WorkflowGraphDraft"},"repair":{"type":"boolean","description":"When true, simple repairs are applied to validation.graph."}},"required":["draft"]}}}},"responses":{"200":{"description":"Validation report.","content":{"application/json":{"schema":{"type":"object","properties":{"validation":{"$ref":"#/components/schemas/WorkflowValidationResult"}}}}}}}}},"/api/workflows/repair":{"post":{"operationId":"repairWorkflowDraft","summary":"Repair a workflow graph draft without saving it","tags":["Workflow Agents"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"draft":{"$ref":"#/components/schemas/WorkflowGraphDraft"}},"required":["draft"]}}}},"responses":{"200":{"description":"Repaired graph draft and validation report.","content":{"application/json":{"schema":{"type":"object","properties":{"draft":{"$ref":"#/components/schemas/WorkflowGraphDraft"},"validation":{"$ref":"#/components/schemas/WorkflowValidationResult"}}}}}}}}},"/api/api-keys":{"get":{"operationId":"listApiKeys","summary":"List your API keys","tags":["API Keys"],"responses":{"200":{"description":"List of API keys (no secrets)","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyInfo"}}}}}}}}},"post":{"operationId":"createApiKey","summary":"Generate a new API key","tags":["API Keys"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","description":"Human-readable label","default":"Default"}}}}}},"responses":{"201":{"description":"New API key created. The key field is shown only once.","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","description":"Plaintext API key (shown once)"},"keyId":{"type":"string"}}}}}}}},"delete":{"operationId":"revokeApiKey","summary":"Revoke an API key","tags":["API Keys"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string"}},"required":["keyId"]}}}},"responses":{"200":{"description":"Key revoked"},"404":{"description":"Key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}