newcharactersheet
newcharactersheetChecking account...

API Reference

newcharactersheet API

Generate character sheets and scenes programmatically. The default path is credit-based generation with API-key auth.

Credits defaultAgent ready/api/openapi.json

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.

1

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"
2

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"
3

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.

Image / character10 / 12 / 25 credits
Audiofrom 5 credits
Video50 / 100 / 200 / 400 credits at default length
3D model150 credits

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 with SOL or USDC on Solana. Create an order for the pack, send one wallet transaction for the quoted amount, then verify it to receive the credits. USDC is charged at the pack's USD price; SOL is quoted at the live market price when the order is created. Orders expire after 15 minutes.

GET/api/credits/balanceRequiredLink
Get credit balance and recent transactionsOpen

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/api/billingRequiredLink
Get billing mode and provider availabilityOpen

Response

{
  "mode": "CREDITS",
  "managedPlanAvailable": false,
  "creditsAvailable": true,
  "platformProviders": ["nanobanana", "replicate"],
  "hasByoApiKey": false,
  "imageProvider": "nanobanana",
  "videoProvider": "nanobanana"
}
PUT/api/billingRequiredLink
Switch billing mode or save a provider keyOpen

Use CREDITS for account credits, or BYO for saved provider keys. Saving a provider key switches the account to BYO mode.

Parameters

FieldTypeRequiredDescription
mode"CREDITS" | "BYO" | "MANAGED"NoBilling mode for future generations
providerNamestringNoProvider name when saving a BYO key
apiKeystringNoProvider API key to encrypt and save

Request body

{
  "mode": "CREDITS"
}

Response

{
  "mode": "CREDITS",
  "creditsAvailable": true,
  "hasByoApiKey": false
}
POST/api/credits/checkoutRequiredLink
Create a SOL or USDC payment order for a credit packOpen

Quotes the pack in the chosen token. Pay by sending one Solana transaction that transfers tokenAmountRaw to treasuryWallet and includes the order memo, then call POST /api/credits/checkout/verify. Orders expire after 15 minutes.

Parameters

FieldTypeRequiredDescription
packageId"starter" | "creator" | "studio" | "enterprise"YesCredit pack to buy
paymentToken"SOL" | "USDC"YesToken to pay with
returnPathstringNoApp path stored with the order

Request body

{
  "packageId": "starter",
  "paymentToken": "USDC",
  "returnPath": "/settings"
}

Response

{
  "order": {
    "orderId": "c3145f43-...",
    "paymentKind": "credit_purchase",
    "packageId": "starter",
    "credits": 1000,
    "priceUsd": 10,
    "tokenSymbol": "USDC",
    "tokenAmount": "10",
    "tokenAmountRaw": "10000000",
    "tokenDecimals": 6,
    "pricingSource": "jupiter",
    "pricingMode": "spot_bootstrap",
    "tokenUsdPrice": 1,
    "mintAddress": "...",
    "treasuryWallet": "...",
    "memo": "newcharactersheet:credits:c3145f43-...:uid",
    "expiresAt": 1760000000000
  }
}
POST/api/credits/checkout/verifyRequiredLink
Verify a confirmed SOL or USDC payment and grant creditsOpen

Checks the Solana transaction against the pending order (amount, recipient, signer, and memo) and grants the credits. Safe to retry: a payment is only credited once.

Parameters

FieldTypeRequiredDescription
orderIdstringYesPending order returned by /api/credits/checkout
signaturestringYesConfirmed Solana transaction signature
walletAddressstringYesWallet that signed and sent the payment

Request body

{
  "orderId": "c3145f43-...",
  "signature": "5Ue...",
  "walletAddress": "9xQe..."
}

Response

{
  "ok": true,
  "balance": 1300,
  "credits": 1000,
  "signature": "5Ue..."
}
POST/api/credits/stripe-checkoutRequiredLink
Create a Stripe checkout for a credit pack (legacy)Open

Legacy flow: credits are now bought with SOL or USDC via POST /api/credits/checkout. Stripe no longer sells base credit packs.

Parameters

FieldTypeRequiredDescription
packageId"starter" | "creator" | "studio" | "enterprise"YesCredit pack to buy with Stripe
returnPathstringNoApp path Stripe returns to after payment or cancellation

Request body

{
  "packageId": "starter",
  "returnPath": "/settings"
}

Response

{
  "url": "https://checkout.stripe.com/c/pay/cs_test_..."
}
Top-up packCreditsUSD priceSOL / USDC price
starter1000$10Quoted at checkout
creator3000$30Quoted at checkout
studio11000$100Quoted at checkout
enterprise30000$260Quoted at checkout

Map

Endpoint Index

A compact routing table for people and agents. Each row links to the detailed endpoint contract below.

MethodPathAuthPurpose
GET/api/auth/meOptionalCheck auth status
GET/api/credits/balanceRequiredRead credit balance
GET/api/billingRequiredRead billing mode
PUT/api/billingRequiredSwitch billing or save a provider key
POST/api/credits/checkoutRequiredCreate a SOL or USDC credit-pack order
POST/api/credits/checkout/verifyRequiredVerify a SOL or USDC payment
POST/api/credits/stripe-checkoutRequiredCreate a Stripe credit-pack checkout (legacy)
POST/api/generateRequiredGenerate a character sheet
POST/api/scene/generateRequiredGenerate a scene image
POST/api/scene/video-previewRequiredGenerate a scene video
GET/api/sheets/:idOptionalFetch a sheet
PATCH/api/sheets/:idRequiredUpdate sheet metadata
DELETE/api/sheets/:idRequiredDelete a sheet
GET/api/sheets/search?q=queryOptionalSearch public sheets
PATCH/api/visibility/:idRequiredChange visibility
GET/api/api-keysRequiredList API key metadata
POST/api/api-keysRequiredCreate an API key
DELETE/api/api-keysRequiredRevoke an API key

Identity

Auth

GET/api/auth/meOptionalLink
Check authentication statusOpen

Response

{
  "authenticated": true,
  "uid": "fWx8k2mN..."
}

Create

Generation

POST/api/generateRequiredLink
Generate a character reference sheetOpen

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

FieldTypeRequiredDescription
promptstringYesCharacter description (max 10,000 chars)
keywordsstringNoComma-separated tags
visibilitystringNo"public" or "private" (default)
stylestringNoArt style hint
referenceImagesfile[]NoReference images (max 50 MB each)
projectMode"new" | "existing"NoAttach the sheet to a project
projectIdstringNoExisting project ID when projectMode is existing
projectNamestringNoNew project name when projectMode is new
folderIdstringNoFolder 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..."
}
POST/api/scene/generateRequiredLink
Generate a scene image with charactersOpen

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

FieldTypeRequiredDescription
promptstringNoScene description
sheetIdsstring[]NoCharacter sheet IDs to include (max 8)
outputModestringNo"picture" by default; video workflows use dedicated video endpoints
projectMode"new" | "existing"NoAttach the scene to a project
existingProjectIdstringNoExisting project ID when projectMode is existing
projectNamestringNoNew 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_..."
POST/api/scene/video-previewRequiredLink
Generate a scene videoOpen

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

FieldTypeRequiredDescription
promptstringNoVideo prompt (max 10,000 chars)
sheetIdsstring[]NoCharacter sheet IDs to reference (max 8)
sceneIdsstring[]NoScene sheet IDs to reference (max 4)
firstImageIdstringNoSheet ID to use as the first frame
lastImageIdstringNoSheet ID to use as the last frame for interpolation
firstFrameImageobjectNoInline first-frame image payload
lastFrameImageobjectNoInline last-frame image payload
durationSecondsnumberNoRequested duration, clamped by model capability
aspectRatiostringNoExample: "16:9", "9:16", "1:1"
resolutionstringNoModel-specific resolution option
modelOverridestringNoVideo model ID to use
providerJobobjectNoPass 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/api/sheets/:idOptionalLink
Get a sheet by IDOpen

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
}
PATCH/api/sheets/:idRequiredLink
Update sheet metadataOpen

Request body

{
  "keywords": ["knight", "medieval", "armor"],
  "handle": "golden-knight"
}

Response

{
  "id": "6d3f...",
  "keywords": ["knight", "medieval", "armor"],
  "handle": "golden-knight"
}
DELETE/api/sheets/:idRequiredLink
Delete a sheet you ownOpen

Returns 204 with no body.

PATCH/api/visibility/:idRequiredLink
Change sheet visibilityOpen

Request body

{ "visibility": "public" }

Response

{
  "id": "6d3f...",
  "visibility": "public"
}

Access

API Keys

GET/api/api-keysRequiredLink
List your API keysOpen

Returns metadata only. Plaintext key secrets are never returned after creation.

Response

{
  "keys": [
    {
      "keyId": "a1b2c3...",
      "label": "my-agent",
      "last4": "Zw4x",
      "createdAt": 1708300000000
    }
  ]
}
POST/api/api-keysRequiredLink
Create a new API keyOpen

The plaintext key is returned only once.

Request body

{ "label": "production" }

Response 201

{
  "key": "ncs_dG9rZW4...",
  "keyId": "a1b2c3..."
}
DELETE/api/api-keysRequiredLink
Revoke an API keyOpen

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.

ScopeLimit
Global reads2,000 requests / minute per IP
Global writes300 requests / minute per IP
Generation routes10 requests / minute per IP
API key daily quota1,000 requests / day per key
Prompt length10,000 characters
File size50 MB each, 100 MB total
Reference imagesMax 8 per request

Responses

Errors

{
  "error": {
    "code": "UNAUTHENTICATED",
    "message": "Authentication required"
  }
}
401402403404429500

Rate-limited responses return 429 with Retry-After. Insufficient credits return 402 with INSUFFICIENT_CREDITS.