API Reference
newcharactersheet API
Generate character sheets and scenes programmatically. The default path is credit-based generation with API-key auth.
Read first
Agent Brief
- Base URL
https://newcharactersheet.com- Auth header
X-API-Key: ncs_...- Default billing
CREDITS when platform keys are configured- Generate response
POST /api/generate returns { id }- Video endpoint
POST /api/scene/video-preview returns videoUrl or pending- Fetch assets
GET /api/sheets/:id returns accessUrl fields- OpenAPI
/api/openapi.json
Start here
Quick Start
Three calls cover the normal integration path: confirm auth, check credits, generate, then fetch the saved sheet.
Create or reuse an API key
Sign in at Settings, then create an API key. Keys begin with ncs_.
curl https://newcharactersheet.com/api/auth/me \
-H "X-API-Key: ncs_your_key_here"Check credits before work
New accounts receive 300 credits by default. Top-up credits do not expire.
curl https://newcharactersheet.com/api/credits/balance \
-H "X-API-Key: ncs_your_key_here"Generate and fetch
Generation returns the sheet ID. Fetch the sheet to get signed or public asset URLs.
curl -X POST https://newcharactersheet.com/api/generate \
-H "X-API-Key: ncs_your_key_here" \
-F "prompt=A cyberpunk street samurai with neon tattoos" \
-F "visibility=private"
curl https://newcharactersheet.com/api/sheets/6d3f... \
-H "X-API-Key: ncs_your_key_here"Default model
Billing & Credits
Credit-based billing is the default account mode when platform model keys are available. Credits are spent before generation and refunded when credit-mode generation fails.
Subscription credits reset each billing cycle. Top-up credits do not expire and are spent after subscription credits.
Provider-key mode is still available for accounts that want to use their own model provider keys.
Get credit balance and recent transactions
Response
{
"balance": 1000,
"subscriptionCredits": 0,
"topUpCredits": 1000,
"tier": "free",
"totalPurchased": 1000,
"totalSpent": 0,
"transactions": [
{
"id": "txn_abc...",
"type": "purchase",
"amount": 1000,
"balance": 1000,
"description": "Starter credit pack",
"createdAt": 1708300000000
}
]
}Get billing mode and provider availability
Response
{
"mode": "CREDITS",
"managedPlanAvailable": false,
"creditsAvailable": true,
"platformProviders": ["nanobanana", "replicate"],
"hasByoApiKey": false,
"imageProvider": "nanobanana",
"videoProvider": "nanobanana"
}Switch billing mode or save a provider key
Use CREDITS for account credits, or BYO for saved provider keys. Saving a provider key switches the account to BYO mode.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
mode | "CREDITS" | "BYO" | "MANAGED" | No | Billing mode for future generations |
providerName | string | No | Provider name when saving a BYO key |
apiKey | string | No | Provider API key to encrypt and save |
Request body
{
"mode": "CREDITS"
}Response
{
"mode": "CREDITS",
"creditsAvailable": true,
"hasByoApiKey": false
}Create a Stripe checkout session for credit top-ups
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
packageId | "starter" | "creator" | "studio" | "enterprise" | Yes | Credit pack to buy |
returnPath | string | No | App path for success/cancel redirects |
Request body
{
"packageId": "starter",
"returnPath": "/settings"
}Response
{
"url": "https://checkout.stripe.com/c/pay/cs_test_..."
}| Top-up pack | Credits | Price |
|---|---|---|
starter | 1000 | $10 |
creator | 3000 | $30 |
studio | 11000 | $100 |
enterprise | 30000 | $260 |
Map
Endpoint Index
A compact routing table for people and agents. Each row links to the detailed endpoint contract below.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /api/auth/me | Optional | Check auth status |
| GET | /api/credits/balance | Required | Read credit balance |
| GET | /api/billing | Required | Read billing mode |
| PUT | /api/billing | Required | Switch billing or save a provider key |
| POST | /api/credits/checkout | Required | Buy top-up credits |
| POST | /api/generate | Required | Generate a character sheet |
| POST | /api/scene/generate | Required | Generate a scene image |
| POST | /api/scene/video-preview | Required | Generate a scene video |
| GET | /api/sheets/:id | Optional | Fetch a sheet |
| PATCH | /api/sheets/:id | Required | Update sheet metadata |
| DELETE | /api/sheets/:id | Required | Delete a sheet |
| GET | /api/sheets/search?q=query | Optional | Search public sheets |
| PATCH | /api/visibility/:id | Required | Change visibility |
| GET | /api/api-keys | Required | List API key metadata |
| POST | /api/api-keys | Required | Create an API key |
| DELETE | /api/api-keys | Required | Revoke an API key |
Identity
Auth
Check authentication status
Response
{
"authenticated": true,
"uid": "fWx8k2mN..."
}Create
Generation
Generate a character reference sheet
Accepts multipart/form-data. In credit mode, image generation usually costs 12 credits and may be lower or higher by model tier. Credits are refunded if generation fails. Returns the new sheet ID; fetch image URLs via GET /api/sheets/:id.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Character description (max 10,000 chars) |
keywords | string | No | Comma-separated tags |
visibility | string | No | "public" or "private" (default) |
style | string | No | Art style hint |
referenceImages | file[] | No | Reference images (max 50 MB each) |
projectMode | "new" | "existing" | No | Attach the sheet to a project |
projectId | string | No | Existing project ID when projectMode is existing |
projectName | string | No | New project name when projectMode is new |
folderId | string | No | Folder to place the generated sheet in |
Request
curl -X POST https://newcharactersheet.com/api/generate \
-H "X-API-Key: ncs_..." \
-F "prompt=A medieval knight with golden armor" \
-F "keywords=knight,medieval,armor" \
-F "visibility=public" \
-F "style=anime"Response 201
{
"id": "6d3f..."
}Generate a scene image with characters
Create a scene image featuring your characters. Scene access still follows the account feature gate; generation uses credits when the account is in CREDITS mode.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | No | Scene description |
sheetIds | string[] | No | Character sheet IDs to include (max 8) |
outputMode | string | No | "picture" by default; video workflows use dedicated video endpoints |
projectMode | "new" | "existing" | No | Attach the scene to a project |
existingProjectId | string | No | Existing project ID when projectMode is existing |
projectName | string | No | New project name when projectMode is new |
Request body
{
"prompt": "Epic battle in a volcanic landscape",
"sheetIds": ["6d3f..."],
"outputMode": "picture"
}Response 201
{
"id": "s9f2...",
"imageBase64": "iVBORw0KGgo...",
"contentType": "image/png",
"outputMode": "picture"
}Workflow Example
Generate a character
curl -X POST https://newcharactersheet.com/api/generate \
-H "X-API-Key: ncs_..." \
-F "prompt=A fire mage with flowing red robes"Create a scene image
curl -X POST https://newcharactersheet.com/api/scene/generate \
-H "X-API-Key: ncs_..." \
-H "Content-Type: application/json" \
-d '{
"prompt": "Standing on a cliff overlooking a burning city",
"sheetIds": ["char_abc..."],
"outputMode": "picture"
}'Fetch the saved scene
curl https://newcharactersheet.com/api/sheets/scene_xyz... \
-H "X-API-Key: ncs_..."Generate a scene video
Direct video generation endpoint. Use a prompt with sheetIds, sceneIds, a first frame, or inline reference images. In credit mode, video cost is model-tiered and charged before submit; resumable provider jobs return pending.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | No | Video prompt (max 10,000 chars) |
sheetIds | string[] | No | Character sheet IDs to reference (max 8) |
sceneIds | string[] | No | Scene sheet IDs to reference (max 4) |
firstImageId | string | No | Sheet ID to use as the first frame |
lastImageId | string | No | Sheet ID to use as the last frame for interpolation |
firstFrameImage | object | No | Inline first-frame image payload |
lastFrameImage | object | No | Inline last-frame image payload |
durationSeconds | number | No | Requested duration, clamped by model capability |
aspectRatio | string | No | Example: "16:9", "9:16", "1:1" |
resolution | string | No | Model-specific resolution option |
modelOverride | string | No | Video model ID to use |
providerJob | object | No | Pass a prior pending providerJob to resume polling without recharging |
Request body
{
"prompt": "Camera slowly pushes in as embers drift through the air",
"sheetIds": ["char_abc..."],
"sceneIds": ["scene_xyz..."],
"durationSeconds": 5,
"aspectRatio": "16:9",
"modelOverride": "veo-3.1-fast-generate-preview"
}Response
{
"videoUrl": "https://...",
"contentType": "video/mp4",
"sourceUri": null,
"videos": [
{
"videoUrl": "https://...",
"contentType": "video/mp4",
"sourceUri": null
}
],
"textResponse": "Here's the generated video. What do you think?"
}Pending providers may return { pending: true, providerName, providerJob }. Poll again with the same providerJob to resume.
Read and manage
Sheets
Get a sheet by ID
Public sheets need no auth. Private sheets require owner auth.
Response
{
"id": "6d3f...",
"ownerUid": "fWx8k2mN...",
"sheetType": "character",
"visibility": "public",
"prompt": "A medieval knight...",
"keywords": ["knight", "medieval"],
"handle": "golden-knight",
"createdAt": 1708300000000,
"updatedAt": 1708300000000,
"image": {
"storagePath": "sheets/...",
"publicUrl": "https://...",
"contentType": "image/png",
"width": 2048,
"height": 2048
},
"accessUrl": "https://...",
"videoAccessUrl": "https://...",
"project": { "id": "proj_1", "name": "My Project" },
"viewerHasLiked": false
}Update sheet metadata
Request body
{
"keywords": ["knight", "medieval", "armor"],
"handle": "golden-knight"
}Response
{
"id": "6d3f...",
"keywords": ["knight", "medieval", "armor"],
"handle": "golden-knight"
}Delete a sheet you own
Returns 204 with no body.
Search sheets
Response
{
"results": [
{
"id": "6d3f...",
"prompt": "A medieval knight...",
"keywords": ["knight", "medieval"],
"handle": "golden-knight",
"imageUrl": "https://..."
}
]
}Change sheet visibility
Request body
{ "visibility": "public" }Response
{
"id": "6d3f...",
"visibility": "public"
}Access
API Keys
List your API keys
Returns metadata only. Plaintext key secrets are never returned after creation.
Response
{
"keys": [
{
"keyId": "a1b2c3...",
"label": "my-agent",
"last4": "Zw4x",
"createdAt": 1708300000000
}
]
}Create a new API key
The plaintext key is returned only once.
Request body
{ "label": "production" }Response 201
{
"key": "ncs_dG9rZW4...",
"keyId": "a1b2c3..."
}Revoke an API key
Request body
{ "keyId": "a1b2c3..." }Response
{ "ok": true }Guardrails
Limits & Quotas
Production API routes are rate-limited per IP. API keys also have a daily request quota. Credit exhaustion returns a separate 402 response.
| Scope | Limit |
|---|---|
| Global reads | 2,000 requests / minute per IP |
| Global writes | 300 requests / minute per IP |
| Generation routes | 10 requests / minute per IP |
| API key daily quota | 1,000 requests / day per key |
| Prompt length | 10,000 characters |
| File size | 50 MB each, 100 MB total |
| Reference images | Max 8 per request |
Responses
Errors
{
"error": {
"code": "UNAUTHENTICATED",
"message": "Authentication required"
}
}401402403404429500Rate-limited responses return 429 with Retry-After. Insufficient credits return 402 with INSUFFICIENT_CREDITS.