Credits and limits

Credits are the currency for video generation. Everything else in the API (rendering, publishing, scheduling, captioning existing footage, registering assets, all reads) is free.

A subscription is not required to create videos: any team with enough credits can generate, whether the credits came from a plan's monthly grant or a one-time top-up. Credit packs are sold at https://faceless.so/billing?tab=credits ($10 for 100 credits, with bonus credits on larger packs), and an agent can buy one itself with POST /credits (see below). Automated series remain a plan feature: creating a series requires an active subscription, and each episode then spends credits like any other video.

What costs credits

Credits are charged once, at video creation, based on the model:

OperationCost
POST /videos with model: "storyboard"20 credits
POST /videos with model: "motion_lite"50 credits
POST /videos with model: "motion_pro"100 credits
Each series episode (automatic or POST /series/{id}/generate)20, 50 or 100, or per second on a Motion tier (below)
POST /fast-track (a Fast Track video)10 credits (3 for Slideshows, Single Fade-in Video and 2x2 Grid Video)

A series made in the app can also run on the per-second Motion tiers the app's create flow offers: Motion 2 credits a second (120 for a one minute episode), Motion Plus 3 and Motion Max 6. Its episodes are charged at that rate on the episode's length. motion_lite and motion_pro are the API's older flat-priced models and are not offered in the app.

Rendering the MP4 and publishing it are free, and re-rendering does not charge again: once a video is created, you can render and publish it without spending more. Deleting a video does not refund its credits.

GET /options?kind=models returns the model catalog with live costs, so agents can pick a model by budget.

Check the balance (GET /credits, scope credits:read)

bash
curl -s https://faceless.so/api/v1/credits \
  -H "Authorization: Bearer $FACELESS_API_KEY"
json
{
	"success": true,
	"data": {
		"balance": 340,
		"history": [
			{
				"id": "665f1b2a9c31a2b3c4d5e701",
				"credits": -50,
				"type": "spending",
				"description": "Faceless video (motion_lite)",
				"createdAt": "2026-07-30T10:00:00.000Z"
			}
		]
	},
	"pagination": { "page": 1, "limit": 20, "total": 1 }
}

The ledger lists purchases, subscription grants, spends and refunds. GET /me also returns the balance if you only need the number. A well-behaved agent checks the balance before a batch of creations and reports spend after.

Buy credits from an agent (POST /credits, scope credits:write)

An agent can top the team up without the dashboard, paying with a Stripe Shared Payment Token (spt_...) that the customer approves in their Link agent wallet. The credits land in the same request.

PackPriceCredits (list rate)
pack_10$10100
pack_25$25275
pack_50$50600

Active subscribers get more credits per pack at their plan's rate; the response reports what was added.

  1. Ask the customer's wallet for a token granted to the Faceless.so Stripe profile (profile_61UDMKC11wsLfeXaMA6UDMKCL0SQKAF3aHKCFz33IPL6), in USD, with max_amount of at least the pack price in cents. With the Link CLI:
bash
npx @stripe/link-cli spend-request create \
  --payment-method-id csmrpd_xxx \
  --context "Faceless.so credit pack pack_10" \
  --amount 1000 \
  --credential-type shared_payment_token \
  --network-id profile_61UDMKC11wsLfeXaMA6UDMKCL0SQKAF3aHKCFz33IPL6 \
  --request-approval
  1. Spend it:
bash
curl -s -X POST https://faceless.so/api/v1/credits \
  -H "Authorization: Bearer $FACELESS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"packId":"pack_10","paymentToken":"spt_..."}'
json
{
	"success": true,
	"data": { "packId": "pack_10", "amountUsd": 10, "creditsAdded": 100, "balance": 440, "paymentIntentId": "pi_..." }
}

Or faceless buy-credits --pack pack_10 --token spt_.... There is no MCP tool for it yet.

Tokens are single use. Retrying a request with the same token never charges twice: it returns the same payment and grants the credits once. A declined, expired, revoked or already used token, or one whose max_amount is below the pack price, fails with 402 payment_failed and grants nothing. Reusing a token for a different pack is 409 conflict. A 5xx (internal_error) from this endpoint means the payment may have gone through without the credits landing: retry with the same token within 24 hours and the credits are granted once, with no second charge. credits:write is its own scope because it spends real money; a key only gets it when you grant it.

Running out: 402 insufficient_credits

A creation the team cannot pay for fails with 402 and error type insufficient_credits. Nothing is charged and nothing is created. Do not retry until the balance changes: buy a pack with POST /credits (above), or top up or upgrade in the dashboard at https://faceless.so/billing.

Plan limits: 403 usage_limit_reached

There is no cap on how many videos a team can store or have generating. What paid plans do cap is the minutes of new video a team creates in a calendar month: Starter 120, Growth 180, Influencer 300, Ultra 1,200, Agency 2,400. Creating a video once the month's total is past the cap fails with 403 and error type usage_limit_reached even when the credit balance is fine. Every video created that month counts, deleted ones included, and the total resets on the 1st, so deleting videos does not free minutes; upgrading the plan or waiting for the new month does. This is not a scope problem (that is forbidden_scope), so changing the key does not help. At short-form lengths credits run out long before minutes do: 4,000 credits make about 200 one minute Storyboard shorts, a sixth of Ultra's 1,200 minutes. Teams without a subscription have no minutes cap; they are metered purely by credits, so they only ever see 402 insufficient_credits.

The same usage_limit_reached type also answers a free team that tries something that needs a paid plan, such as an automated series.

Rate limits

Limits are per API key. Exceeding one returns 429 rate_limited with a Retry-After header in seconds.

OperationLimit
Default (all operations)300 per 60s
POST /credits5 per 60s
POST /videos10 per 60s
POST /videos/captions10 per 300s
POST /videos/{id}/render10 per 300s
POST /series5 per 300s
POST /series/{id}/generate5 per 300s
POST /posts10 per 300s
POST /posts/schedule20 per 300s

Polling GET /videos/{id}/status every 10 to 30 seconds and GET /renders/{id} every 5 to 15 seconds sits comfortably inside the default limit. See errors and rate limits for how to react to 429s and how Idempotency-Key makes retries safe without double-charging.