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.
Video pricing scales with clip length: the tier price covers the model's default duration, and the charge grows or shrinks proportionally when you change the duration setting. A 5-second clip costs a third of a 15-second clip on the same model. Resolution and audio settings can also adjust the price: 4K output doubles the cost, and turning audio off discounts models that price for sound. A few specialty models carry custom per-model pricing above their tier — the cost shown next to the model in the app is authoritative.
Provider-key mode is still available for accounts that want to use their own model provider keys.
One-time credit packs are bought directly with NCS on Solana: one wallet transaction burns part of the quoted amount and sends the rest to the treasury. The split is runtime-configurable by admins — the defaults are 1% burn / 99% treasury — and each order pins its split at creation time. Buyback budgets can be queued from 25% of net revenue only after at least 6 months of runway. The Stripe-pack + 100% NCS burn boost flow below is a legacy, optional mechanic.
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
}Read NCS tokenomics policy and aggregate ledger totals
Response
{
"tokenSymbol": "NCS",
"policy": {
"burnBps": 100,
"burnPercent": "1%",
"buybackNetRevenueBps": 2500,
"buybackMinRunwayMonths": 6
},
"summary": {
"totalCreditPayments": 12,
"totalUsdCreditRevenue": 420,
"totalNcsPaid": 420,
"totalNcsBurned": 4.2,
"totalNcsToTreasury": 415.8,
"totalNcsBoughtBack": 75
},
"recentEvents": []
}Create a Stripe checkout for a credit pack (legacy)
Legacy flow: credits are now bought directly with NCS via POST /api/credits/checkout. Stripe no longer sells base credit packs.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
packageId | "starter" | "creator" | "studio" | "enterprise" | Yes | Credit pack to buy with Stripe |
returnPath | string | No | App path Stripe returns to after payment or cancellation |
Request body
{
"packageId": "starter",
"returnPath": "/settings"
}Response
{
"url": "https://checkout.stripe.com/c/pay/cs_test_..."
}Create a NCS burn order that doubles a paid Stripe pack (legacy)
Legacy, optional mechanic tied to a paid Stripe pack. Boost orders always burn 100% of the quoted NCS (no treasury transfer).
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
stripeSessionId | string | Yes | Paid Stripe Checkout Session that unlocked the boost |
Request body
{
"stripeSessionId": "cs_test_..."
}Response
{
"order": {
"orderId": "c3145f43-...",
"packageId": "starter",
"credits": 1000,
"paymentKind": "credit_boost",
"stripeSessionId": "cs_test_...",
"priceUsd": 10,
"tokenSymbol": "NCS",
"tokenAmount": "250000",
"tokenAmountRaw": "250000000000",
"burnAmount": "250000",
"burnAmountRaw": "250000000000",
"burnBps": 10000,
"treasuryAmount": "0",
"treasuryAmountRaw": "0",
"treasuryBps": 0,
"buybackNetRevenueBps": 2500,
"tokenDecimals": 6,
"pricingMode": "twap",
"pricingSource": "jupiter",
"tokenUsdPrice": 0.00004,
"tokenSpotUsdPrice": 0.000041,
"tokenTwapUsdPrice": 0.00004,
"twapSampleCount": 8,
"mintAddress": "...",
"treasuryWallet": "...",
"memo": "NCS_CREDITS:c3145f43-...:uid",
"expiresAt": 1760000000000
}
}Verify a confirmed NCS payment and grant credits
Verifies the Solana transaction for a pending order (credit purchase or legacy burn boost) and grants the credits. The burn/treasury amounts come from the split pinned on the order at creation time.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
orderId | string | Yes | Pending order returned by /api/credits/checkout or /api/credits/boost/checkout |
signature | string | Yes | Confirmed Solana transaction signature |
walletAddress | string | Yes | Wallet that signed and sent the NCS burn |
Request body
{
"orderId": "c3145f43-...",
"signature": "5Ue...",
"walletAddress": "9xQe..."
}Response
{
"ok": true,
"balance": 1300,
"credits": 1000,
"signature": "5Ue...",
"tokenomics": {
"tokenSymbol": "NCS",
"tokenAmount": "250000",
"burnAmount": "2500",
"burnBps": 100,
"treasuryAmount": "247500",
"treasuryBps": 9900,
"priceUsd": 10,
"tokenUsdPrice": 0.00004,
"pricingMode": "twap",
"pricingSource": "jupiter"
}
}| Top-up pack | Credits | USD price | NCS price | Default burn | Treasury |
|---|---|---|---|---|---|
starter | 1000 | $10 | Quoted at checkout | 1% of quoted NCS | 99% of quoted NCS |
creator | 3000 | $30 | Quoted at checkout | 1% of quoted NCS | 99% of quoted NCS |
studio | 11000 | $100 | Quoted at checkout | 1% of quoted NCS | 99% of quoted NCS |
enterprise | 30000 | $260 | Quoted at checkout | 1% of quoted NCS | 99% of quoted NCS |
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 |
| GET | /api/tokenomics | Public | Read NCS burn and buyback summary |
| POST | /api/credits/stripe-checkout | Required | Create a Stripe credit-pack checkout (legacy) |
| POST | /api/credits/boost/checkout | Required | Create a NCS burn order to double a paid pack (legacy) |
| POST | /api/credits/checkout/verify | Required | Verify a NCS payment or burn boost |
| 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.